diff --git a/src/dorkbox/network/DnsClient.java b/src/dorkbox/network/DnsClient.java deleted file mode 100644 index fe0073d0..00000000 --- a/src/dorkbox/network/DnsClient.java +++ /dev/null @@ -1,807 +0,0 @@ -/* - * Copyright 2010 dorkbox, llc - * - * 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 dorkbox.network; - -import static dorkbox.network.dns.resolver.addressProvider.DnsServerAddressStreamProviders.platformDefault; -import static io.netty.util.internal.ObjectUtil.checkNotNull; -import static io.netty.util.internal.ObjectUtil.intValue; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import org.slf4j.Logger; - -import dorkbox.network.connection.Shutdownable; -import dorkbox.network.dns.DnsQuestion; -import dorkbox.network.dns.clientHandlers.DnsResponse; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.records.DnsRecord; -import dorkbox.network.dns.resolver.DnsNameResolver; -import dorkbox.network.dns.resolver.DnsQueryLifecycleObserverFactory; -import dorkbox.network.dns.resolver.NoopDnsQueryLifecycleObserverFactory; -import dorkbox.network.dns.resolver.addressProvider.DefaultDnsServerAddressStreamProvider; -import dorkbox.network.dns.resolver.addressProvider.DnsServerAddressStreamProvider; -import dorkbox.network.dns.resolver.addressProvider.SequentialDnsServerAddressStreamProvider; -import dorkbox.network.dns.resolver.cache.DefaultDnsCache; -import dorkbox.network.dns.resolver.cache.DnsCache; -import dorkbox.util.NamedThreadFactory; -import dorkbox.util.OS; -import dorkbox.util.Property; -import io.netty.channel.ChannelFactory; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.ReflectiveChannelFactory; -import io.netty.channel.epoll.EpollDatagramChannel; -import io.netty.channel.epoll.EpollEventLoopGroup; -import io.netty.channel.kqueue.KQueueDatagramChannel; -import io.netty.channel.kqueue.KQueueEventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.oio.OioEventLoopGroup; -import io.netty.channel.socket.DatagramChannel; -import io.netty.channel.socket.InternetProtocolFamily; -import io.netty.channel.socket.nio.NioDatagramChannel; -import io.netty.channel.socket.oio.OioDatagramChannel; -import io.netty.resolver.HostsFileEntriesResolver; -import io.netty.resolver.ResolvedAddressTypes; -import io.netty.util.concurrent.Future; - -/** - * A DnsClient for resolving DNS name, with reasonably good defaults. - */ -@SuppressWarnings({"unused", "WeakerAccess"}) -public -class DnsClient extends Shutdownable { - -/* - * TODO: verify ResolverConfiguration works as expected! - * http://bugs.java.com/view_bug.do?bug_id=8176361 - * Previous JDK releases documented how to configure `java.net.InetAddress` to use the JNDI DNS service provider as the name service. - * This mechanism, and the system properties to configure it, have been removed in JDK 9 - * - * A new mechanism to configure the use of a hosts file has been introduced. - * - * A new system property `jdk.net.hosts.file` has been defined. When this system property is set, the name and address resolution calls - * of `InetAddress`, i.e `getByXXX`, retrieve the relevant mapping from the specified file. The structure of this file is equivalent to - * that of the `/etc/hosts` file. - * - * When the system property `jdk.net.hosts.file` is set, and the specified file doesn't exist, the name or address lookup will result in - * an UnknownHostException. Thus, a non existent hosts file is handled as if the file is empty. - * - * UP UNTIL java 1.8, one can use org/xbill/DNS/spi, ie: sun.net.dns.ResolverConfiguration - * - * TODO: add this functionality? https://en.wikipedia.org/wiki/Link-Local_Multicast_Name_Resolution - */ - - - /** - * This is a list of all of the public DNS servers to query, when submitting DNS queries - */ - // @formatter:off - @Property - public static - List DNS_SERVER_LIST = Arrays.asList( - new InetSocketAddress("8.8.8.8", 53), // Google Public DNS - new InetSocketAddress("8.8.4.4", 53), - new InetSocketAddress("208.67.222.222", 53), // OpenDNS - new InetSocketAddress("208.67.220.220", 53), - new InetSocketAddress("37.235.1.174", 53), // FreeDNS - new InetSocketAddress("37.235.1.177", 53) - ); - // @formatter:on - - /** - * This is a list of all of the BOX default DNS servers to query, when submitting DNS queries. - */ - public final static List DEFAULT_DNS_SERVER_LIST = DefaultDnsServerAddressStreamProvider.defaultAddressList(); - - public static final InetAddress[] INET_ADDRESSES = new InetAddress[0]; - - /** - * Gets the version number. - */ - public static - String getVersion() { - return "2.13"; - } - - /** - * Retrieve the public facing IP address of this system using DNS. - *

- * Same command as - *

- * dig +short myip.opendns.com @resolver1.opendns.com - * - * @return the public IP address if found, or null if it didn't find it - */ - public static - InetAddress getPublicIp() { - final InetSocketAddress dnsServer = new InetSocketAddress("208.67.222.222", 53); // openDNS - - DnsClient dnsClient = new DnsClient(dnsServer); - List resolved = null; - try { - resolved = dnsClient.resolve("myip.opendns.com"); - } catch (Throwable ignored) { - } - - dnsClient.stop(); - - if (resolved != null && resolved.size() > 0) { - return resolved.get(0); - } - - return null; - } - - private final Logger logger = org.slf4j.LoggerFactory.getLogger(getClass()); - private Class channelType; - - private DnsNameResolver resolver; - - private ThreadGroup threadGroup; - private static final String THREAD_NAME = "DnsClient"; - - private EventLoopGroup eventLoopGroup; - - private ChannelFactory channelFactory; - - private DnsCache resolveCache; - private DnsCache authoritativeDnsServerCache; - - private Integer minTtl; - private Integer maxTtl; - private Integer negativeTtl; - private long queryTimeoutMillis = 5000; - - private ResolvedAddressTypes resolvedAddressTypes = DnsNameResolver.DEFAULT_RESOLVE_ADDRESS_TYPES; - private boolean recursionDesired = true; - private int maxQueriesPerResolve = 16; - - private boolean traceEnabled; - private int maxPayloadSize = 4096; - - private HostsFileEntriesResolver hostsFileEntriesResolver = HostsFileEntriesResolver.DEFAULT; - private DnsServerAddressStreamProvider dnsServerAddressStreamProvider = platformDefault(); - private DnsQueryLifecycleObserverFactory dnsQueryLifecycleObserverFactory = NoopDnsQueryLifecycleObserverFactory.INSTANCE; - - private String[] searchDomains; - private int ndots = -1; - private boolean decodeIdn = true; - - /** - * Creates a new DNS client, with default name server addresses. - */ - public - DnsClient() { - this(DnsClient.DNS_SERVER_LIST); - } - - /** - * Creates a new DNS client, using the provided server (default port 53) for DNS query resolution, with a cache that will obey the TTL of the response - * - * @param nameServerAddresses the server to receive your DNS questions. - */ - public - DnsClient(final String nameServerAddresses) { - this(nameServerAddresses, 53); - } - - /** - * Creates a new DNS client, using the provided server and por tfor DNS query resolution, with a cache that will obey the TTL of the response - * - * @param nameServerAddresses the server to receive your DNS questions. - */ - public - DnsClient(final String nameServerAddresses, int port) { - this(Collections.singletonList(new InetSocketAddress(nameServerAddresses, port))); - } - - /** - * Creates a new DNS client, using the provided server for DNS query resolution, with a cache that will obey the TTL of the response - * - * @param nameServerAddresses the server to receive your DNS questions. - */ - public - DnsClient(final InetSocketAddress nameServerAddresses) { - this(Collections.singletonList(nameServerAddresses)); - } - - /** - * Creates a new DNS client. - * - * The default TTL value is {@code 0} and {@link Integer#MAX_VALUE}, which practically tells this resolver to - * respect the TTL from the DNS server. - * - * @param nameServerAddresses the list of servers to receive your DNS questions, until it succeeds - */ - public - DnsClient(Collection nameServerAddresses) { - super(DnsClient.class); - - if (OS.isAndroid()) { - // android ONLY supports OIO (not NIO) - eventLoopGroup = new OioEventLoopGroup(1, new NamedThreadFactory(THREAD_NAME + "-DNS", threadGroup)); - channelType = OioDatagramChannel.class; - } - else if (OS.isLinux() && NativeLibrary.isAvailable()) { - // epoll network stack is MUCH faster (but only on linux) - eventLoopGroup = new EpollEventLoopGroup(1, new NamedThreadFactory(THREAD_NAME + "-DNS", threadGroup)); - channelType = EpollDatagramChannel.class; - } - else if (OS.isMacOsX() && NativeLibrary.isAvailable()) { - // KQueue network stack is MUCH faster (but only on macosx) - eventLoopGroup = new KQueueEventLoopGroup(1, new NamedThreadFactory(THREAD_NAME + "-DNS", threadGroup)); - channelType = KQueueDatagramChannel.class; - } - else { - eventLoopGroup = new NioEventLoopGroup(1, new NamedThreadFactory(THREAD_NAME + "-DNS", threadGroup)); - channelType = NioDatagramChannel.class; - } - - manageForShutdown(eventLoopGroup); - - if (nameServerAddresses != null) { - this.dnsServerAddressStreamProvider = new SequentialDnsServerAddressStreamProvider(nameServerAddresses); - } - } - - /** - * Sets the cache for resolution results. - * - * @param resolveCache the DNS resolution results cache - * - * @return {@code this} - */ - public - DnsClient resolveCache(DnsCache resolveCache) { - this.resolveCache = resolveCache; - return this; - } - - /** - * Set the factory used to generate objects which can observe individual DNS queries. - * - * @param lifecycleObserverFactory the factory used to generate objects which can observe individual DNS queries. - * - * @return {@code this} - */ - public - DnsClient dnsQueryLifecycleObserverFactory(DnsQueryLifecycleObserverFactory lifecycleObserverFactory) { - this.dnsQueryLifecycleObserverFactory = checkNotNull(lifecycleObserverFactory, "lifecycleObserverFactory"); - return this; - } - - /** - * Sets the cache for authoritative NS servers - * - * @param authoritativeDnsServerCache the authoritative NS servers cache - * - * @return {@code this} - */ - public - DnsClient authoritativeDnsServerCache(DnsCache authoritativeDnsServerCache) { - this.authoritativeDnsServerCache = authoritativeDnsServerCache; - return this; - } - - /** - * Sets the minimum and maximum TTL of the cached DNS resource records (in seconds). If the TTL of the DNS - * resource record returned by the DNS server is less than the minimum TTL or greater than the maximum TTL, - * this resolver will ignore the TTL from the DNS server and use the minimum TTL or the maximum TTL instead - * respectively. - * The default value is {@code 0} and {@link Integer#MAX_VALUE}, which practically tells this resolver to - * respect the TTL from the DNS server. - * - * @param minTtl the minimum TTL - * @param maxTtl the maximum TTL - * - * @return {@code this} - */ - public - DnsClient ttl(int minTtl, int maxTtl) { - this.maxTtl = maxTtl; - this.minTtl = minTtl; - return this; - } - - /** - * Sets the TTL of the cache for the failed DNS queries (in seconds). - * - * @param negativeTtl the TTL for failed cached queries - * - * @return {@code this} - */ - public - DnsClient negativeTtl(int negativeTtl) { - this.negativeTtl = negativeTtl; - return this; - } - - /** - * Sets the timeout of each DNS query performed by this resolver (in milliseconds). - * - * @param queryTimeoutMillis the query timeout - * - * @return {@code this} - */ - public - DnsClient queryTimeoutMillis(long queryTimeoutMillis) { - this.queryTimeoutMillis = queryTimeoutMillis; - return this; - } - - /** - * Sets the list of the protocol families of the address resolved. - * You can use {@link DnsClient#computeResolvedAddressTypes(InternetProtocolFamily...)} - * to get a {@link ResolvedAddressTypes} out of some {@link InternetProtocolFamily}s. - * - * @param resolvedAddressTypes the address types - * - * @return {@code this} - */ - public - DnsClient resolvedAddressTypes(ResolvedAddressTypes resolvedAddressTypes) { - this.resolvedAddressTypes = resolvedAddressTypes; - return this; - } - - /** - * Sets if this resolver has to send a DNS query with the RD (recursion desired) flag set. - * - * @param recursionDesired true if recursion is desired - * - * @return {@code this} - */ - public - DnsClient recursionDesired(boolean recursionDesired) { - this.recursionDesired = recursionDesired; - return this; - } - - /** - * Sets the maximum allowed number of DNS queries to send when resolving a host name. - * - * @param maxQueriesPerResolve the max number of queries - * - * @return {@code this} - */ - public - DnsClient maxQueriesPerResolve(int maxQueriesPerResolve) { - this.maxQueriesPerResolve = maxQueriesPerResolve; - return this; - } - - /** - * Sets if this resolver should generate the detailed trace information in an exception message so that - * it is easier to understand the cause of resolution failure. - * - * @param traceEnabled true if trace is enabled - * - * @return {@code this} - */ - public - DnsClient traceEnabled(boolean traceEnabled) { - this.traceEnabled = traceEnabled; - return this; - } - - /** - * Sets the capacity of the datagram packet buffer (in bytes). The default value is {@code 4096} bytes. - * - * @param maxPayloadSize the capacity of the datagram packet buffer - * - * @return {@code this} - */ - public - DnsClient maxPayloadSize(int maxPayloadSize) { - this.maxPayloadSize = maxPayloadSize; - return this; - } - - /** - * @param hostsFileEntriesResolver the {@link HostsFileEntriesResolver} used to first check - * if the hostname is locally aliased. - * - * @return {@code this} - */ - public - DnsClient hostsFileEntriesResolver(HostsFileEntriesResolver hostsFileEntriesResolver) { - this.hostsFileEntriesResolver = hostsFileEntriesResolver; - return this; - } - - /** - * Set the {@link DnsServerAddressStreamProvider} which is used to determine which DNS server is used to resolve - * each hostname. - * - * @return {@code this} - */ - public - DnsClient nameServerProvider(DnsServerAddressStreamProvider dnsServerAddressStreamProvider) { - this.dnsServerAddressStreamProvider = checkNotNull(dnsServerAddressStreamProvider, "dnsServerAddressStreamProvider"); - return this; - } - - /** - * Set the list of search domains of the resolver. - * - * @param searchDomains the search domains - * - * @return {@code this} - */ - public - DnsClient searchDomains(Iterable searchDomains) { - checkNotNull(searchDomains, "searchDomains"); - - final List list = new ArrayList(4); - - for (String f : searchDomains) { - if (f == null) { - break; - } - - // Avoid duplicate entries. - if (list.contains(f)) { - continue; - } - - list.add(f); - } - - this.searchDomains = list.toArray(new String[list.size()]); - return this; - } - - /** - * Set the number of dots which must appear in a name before an initial absolute query is made. - * The default value is {@code 1}. - * - * @param ndots the ndots value - * - * @return {@code this} - */ - public - DnsClient ndots(int ndots) { - this.ndots = ndots; - return this; - } - - private - DnsCache newCache() { - return new DefaultDnsCache(intValue(minTtl, 0), intValue(maxTtl, Integer.MAX_VALUE), intValue(negativeTtl, 0)); - } - - /** - * Set if domain / host names should be decoded to unicode when received. - * See rfc3492. - * - * @param decodeIdn if should get decoded - * - * @return {@code this} - */ - public - DnsClient decodeToUnicode(boolean decodeIdn) { - this.decodeIdn = decodeIdn; - return this; - } - - - /** - * Compute a {@link ResolvedAddressTypes} from some {@link InternetProtocolFamily}s. - * An empty input will return the default value, based on "java.net" System properties. - * Valid inputs are (), (IPv4), (IPv6), (Ipv4, IPv6) and (IPv6, IPv4). - * - * @param internetProtocolFamilies a valid sequence of {@link InternetProtocolFamily}s - * - * @return a {@link ResolvedAddressTypes} - */ - public static - ResolvedAddressTypes computeResolvedAddressTypes(InternetProtocolFamily... internetProtocolFamilies) { - if (internetProtocolFamilies == null || internetProtocolFamilies.length == 0) { - return DnsNameResolver.DEFAULT_RESOLVE_ADDRESS_TYPES; - } - if (internetProtocolFamilies.length > 2) { - throw new IllegalArgumentException("No more than 2 InternetProtocolFamilies"); - } - - switch (internetProtocolFamilies[0]) { - case IPv4: - return (internetProtocolFamilies.length >= 2 && internetProtocolFamilies[1] == InternetProtocolFamily.IPv6) - ? ResolvedAddressTypes.IPV4_PREFERRED - : ResolvedAddressTypes.IPV4_ONLY; - case IPv6: - return (internetProtocolFamilies.length >= 2 && internetProtocolFamilies[1] == InternetProtocolFamily.IPv4) - ? ResolvedAddressTypes.IPV6_PREFERRED - : ResolvedAddressTypes.IPV6_ONLY; - default: - throw new IllegalArgumentException("Couldn't resolve ResolvedAddressTypes from InternetProtocolFamily array"); - } - } - - - /** - * Starts the DNS Name Resolver for the client, which will resolve DNS queries. - */ - public - DnsClient start() { - ReflectiveChannelFactory channelFactory = new ReflectiveChannelFactory(channelType); - - // default support is IPV4 - if (this.resolvedAddressTypes == null) { - this.resolvedAddressTypes = ResolvedAddressTypes.IPV4_ONLY; - } - - if (resolveCache != null && (minTtl != null || maxTtl != null || negativeTtl != null)) { - throw new IllegalStateException("resolveCache and TTLs are mutually exclusive"); - } - - if (authoritativeDnsServerCache != null && (minTtl != null || maxTtl != null || negativeTtl != null)) { - throw new IllegalStateException("authoritativeDnsServerCache and TTLs are mutually exclusive"); - } - - DnsCache resolveCache = this.resolveCache != null ? this.resolveCache : newCache(); - DnsCache authoritativeDnsServerCache = this.authoritativeDnsServerCache != null ? this.authoritativeDnsServerCache : newCache(); - - resolver = new DnsNameResolver(eventLoopGroup.next(), - channelFactory, - resolveCache, - authoritativeDnsServerCache, - dnsQueryLifecycleObserverFactory, - queryTimeoutMillis, - resolvedAddressTypes, - recursionDesired, - maxQueriesPerResolve, - traceEnabled, - maxPayloadSize, - hostsFileEntriesResolver, - dnsServerAddressStreamProvider, - searchDomains, - ndots, - decodeIdn); - - return this; - } - - /** - * Clears the DNS resolver cache - */ - public - void reset() { - if (resolver == null) { - start(); - } - - clearResolver(); - } - - private - void clearResolver() { - resolver.resolveCache() - .clear(); - } - - @Override - protected - void stopExtraActions() { - if (resolver != null) { - clearResolver(); - - resolver.close(); // also closes the UDP channel that DNS client uses - } - } - - - /** - * Resolves a specific hostname A/AAAA record with the default timeout of 5 seconds - * - * @param hostname the hostname, ie: google.com, that you want to resolve - * - * @return the list of resolved InetAddress or throws an exception if the hostname cannot be resolved - * @throws UnknownHostException if the hostname cannot be resolved - */ - public - List resolve(String hostname) throws UnknownHostException { - return resolve(hostname, 5); - } - - /** - * Resolves a specific hostname A/AAAA record. - * - * @param hostname the hostname, ie: google.com, that you want to resolve - * @param queryTimeoutSeconds the number of seconds to wait for host resolution - * - * @return the list of resolved InetAddress or throws an exception if the hostname cannot be resolved - * @throws UnknownHostException if the hostname cannot be resolved - */ - public - List resolve(String hostname, int queryTimeoutSeconds) throws UnknownHostException { - if (hostname == null) { - throw new UnknownHostException("Cannot submit query for an unknown host"); - } - - if (resolver == null) { - start(); - } - - // use "resolve", since it handles A/AAAA records + redirects correctly - final Future> resolve = resolver.resolveAll(hostname); - - boolean finished = resolve.awaitUninterruptibly(queryTimeoutSeconds, TimeUnit.SECONDS); - - // now return whatever value we had - if (finished && resolve.isSuccess() && resolve.isDone()) { - try { - List now = resolve.getNow(); - return now; - } catch (Exception e) { - String msg = "Could not ask question to DNS server"; - logger.error(msg, e); - throw new UnknownHostException(msg); - } - } - - String msg = "Could not ask question to DNS server for A/AAAA record: " + hostname; - logger.error(msg); - - UnknownHostException cause = (UnknownHostException) resolve.cause(); - if (cause != null) { - throw cause; - } - - throw new UnknownHostException(msg); - } - - /** - * @return the DNS resolver used by the client. This is for more advanced functionality - */ - public - DnsNameResolver getResolver() { - return resolver; - } - - /** - * Resolves a specific hostname record, of the specified type (PTR, MX, TXT, etc) with the default timeout of 5 seconds - *

- *

- * Note: PTR queries absolutely MUST end in '.in-addr.arpa' in order for the DNS server to understand it. - * -- because of this, we will automatically fix this in case that clients are unaware of this requirement - *

- *

- * Note: A/AAAA queries absolutely MUST end in a '.' -- because of this we will automatically fix this in case that clients are - * unaware of this requirement - * - * @param hostname the hostname, ie: google.com, that you want to resolve - * @param type the DnsRecordType you want to resolve (PTR, MX, TXT, etc) - * - * @return the DnsRecords or throws an exception if the hostname cannot be resolved - * - * @throws @throws UnknownHostException if the hostname cannot be resolved - */ - @SuppressWarnings({"unchecked", "Duplicates"}) - public - DnsRecord[] query(String hostname, final int type) throws UnknownHostException { - return query(hostname, type, 5); - } - - /** - * Resolves a specific hostname record, of the specified type (PTR, MX, TXT, etc) - *

- *

- * Note: PTR queries absolutely MUST end in '.in-addr.arpa' in order for the DNS server to understand it. - * -- because of this, we will automatically fix this in case that clients are unaware of this requirement - *

- *

- * Note: A/AAAA queries absolutely MUST end in a '.' -- because of this we will automatically fix this in case that clients are - * unaware of this requirement - * - * @param hostname the hostname, ie: google.com, that you want to resolve - * @param type the DnsRecordType you want to resolve (PTR, MX, TXT, etc) - * @param queryTimeoutSeconds the number of seconds to wait for host resolution - * - * @return the DnsRecords or throws an exception if the hostname cannot be resolved - * - * @throws @throws UnknownHostException if the hostname cannot be resolved - */ - @SuppressWarnings({"unchecked", "Duplicates"}) - public - DnsRecord[] query(String hostname, final int type, int queryTimeoutSeconds) throws UnknownHostException { - if (hostname == null) { - throw new UnknownHostException("Cannot submit query for an unknown host"); - } - - if (resolver == null) { - start(); - } - - // we use our own resolvers - DnsQuestion dnsMessage = DnsQuestion.newQuery(hostname, type, recursionDesired); - - return query(dnsMessage, queryTimeoutSeconds); - } - - - /** - * Resolves a specific DnsQuestion - *

- *

- * Note: PTR queries absolutely MUST end in '.in-addr.arpa' in order for the DNS server to understand it. - * -- because of this, we will automatically fix this in case that clients are unaware of this requirement - *

- *

- * Note: A/AAAA queries absolutely MUST end in a '.' -- because of this we will automatically fix this in case that clients are - * unaware of this requirement - * - * @param queryTimeoutSeconds the number of seconds to wait for host resolution - * - * @return the DnsRecords or throws an exception if the hostname cannot be resolved - * - * @throws @throws UnknownHostException if the hostname cannot be resolved - */ - public - DnsRecord[] query(final DnsQuestion dnsMessage, final int queryTimeoutSeconds) throws UnknownHostException { - int questionCount = dnsMessage.getHeader() - .getCount(DnsSection.QUESTION); - - if (questionCount > 1) { - throw new UnknownHostException("Cannot ask more than 1 question at a time! You tried to ask " + questionCount + " questions at once"); - } - - final int type = dnsMessage.getQuestion() - .getType(); - - final Future query = resolver.query(dnsMessage); - boolean finished = query.awaitUninterruptibly(queryTimeoutSeconds, TimeUnit.SECONDS); - - // now return whatever value we had - if (finished && query.isSuccess() && query.isDone()) { - DnsResponse response = query.getNow(); - try { - final int code = response.getHeader() - .getRcode(); - if (code == DnsResponseCode.NOERROR) { - return response.getSectionArray(DnsSection.ANSWER); - } - - String msg = "Could not ask question to DNS server: Error code " + code + " for type: " + type + " - " + DnsRecordType.string(type); - logger.error(msg); - - throw new UnknownHostException(msg); - } finally { - response.release(); - } - } - - String msg = "Could not ask question to DNS server for type: " + DnsRecordType.string(type); - logger.error(msg); - - UnknownHostException cause = (UnknownHostException) query.cause(); - if (cause != null) { - throw cause; - } - - throw new UnknownHostException(msg); - - } -} - diff --git a/src/dorkbox/network/DnsServer.java b/src/dorkbox/network/DnsServer.java deleted file mode 100644 index c5d0a591..00000000 --- a/src/dorkbox/network/DnsServer.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network; - -import java.util.ArrayList; - -import org.slf4j.Logger; - -import dorkbox.network.connection.EndPoint; -import dorkbox.network.connection.Shutdownable; -import dorkbox.network.dns.DnsQuestion; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.records.ARecord; -import dorkbox.network.dns.serverHandlers.DnsServerHandler; -import dorkbox.util.NamedThreadFactory; -import dorkbox.util.OS; -import dorkbox.util.Property; -import io.netty.bootstrap.Bootstrap; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.buffer.PooledByteBufAllocator; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelOption; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.WriteBufferWaterMark; -import io.netty.channel.epoll.EpollDatagramChannel; -import io.netty.channel.epoll.EpollEventLoopGroup; -import io.netty.channel.epoll.EpollServerSocketChannel; -import io.netty.channel.kqueue.KQueueDatagramChannel; -import io.netty.channel.kqueue.KQueueEventLoopGroup; -import io.netty.channel.kqueue.KQueueServerSocketChannel; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.oio.OioEventLoopGroup; -import io.netty.channel.socket.nio.NioDatagramChannel; -import io.netty.channel.socket.nio.NioServerSocketChannel; -import io.netty.channel.socket.oio.OioDatagramChannel; -import io.netty.channel.socket.oio.OioServerSocketChannel; -import io.netty.util.NetUtil; - -/** - * from: https://blog.cloudflare.com/how-the-consumer-product-safety-commission-is-inadvertently-behind-the-internets-largest-ddos-attacks/ - * - * NOTE: CloudFlare has anti-DNS reflection protections in place. Specifically, we automatically upgrade from UDP to TCP when a DNS response - * is particularly large (generally, over 512 bytes). Since TCP requires a handshake, it prevents source IP address spoofing which is - * necessary for a DNS amplification attack. - * - * In addition, we rate limit unknown resolvers. Again, this helps ensure that our infrastructure can't be abused to amplify attacks. - * - * Finally, across our DNS infrastructure we have deprecated ANY queries and have proposed to the IETF to restrict ANY queries to only - * authorized parties. By neutering ANY, we've significantly reduced the maximum size of responses even for zone files that need to be - * large due to a large number of records. - * - * - * - * ALSO: see LINK-LOCAL MULTICAST NAME RESOLUTION - * https://en.wikipedia.org/wiki/Link-Local_Multicast_Name_Resolution - * - * In responding to queries, responders listen on UDP port 5355 on the following link-scope Multicast address: - * - * IPv4 - 224.0.0.252, MAC address of 01-00-5E-00-00-FC - * IPv6 - FF02:0:0:0:0:0:1:3 (this notation can be abbreviated as FF02::1:3), MAC address of 33-33-00-01-00-03 - * The responders also listen on TCP port 5355 on the unicast address that the host uses to respond to queries. - */ -public -class DnsServer extends Shutdownable { - - /** - * The maximum queue length for incoming connection indications (a request to connect). If a connection indication arrives when the - * queue is full, the connection is refused. - */ - @Property - public static int backlogConnectionCount = 50; - - private final ServerBootstrap tcpBootstrap; - private final Bootstrap udpBootstrap; - - private final int tcpPort; - private final int udpPort; - private final String hostName; - - public static - void main(String[] args) { - DnsServer server = new DnsServer("localhost", 2053); - - // MasterZone zone = new MasterZone(); - - - server.aRecord("google.com", DnsClass.IN, 10, "127.0.0.1"); - - // server.bind(false); - server.bind(); - - - // DnsClient client = new DnsClient("localhost", 2053); - // List resolve = null; - // try { - // resolve = client.resolve("google.com"); - // } catch (UnknownHostException e) { - // e.printStackTrace(); - // } - // System.err.println("RESOLVED: " + resolve); - // client.stop(); - // server.stop(); - } - - private final DnsServerHandler dnsServerHandler; - - public - DnsServer(String host, int port) { - super(DnsServer.class); - - tcpPort = port; - udpPort = port; - - if (host == null) { - hostName = "0.0.0.0"; - } - else { - hostName = host; - } - - dnsServerHandler = new DnsServerHandler(logger); - String threadName = DnsServer.class.getSimpleName(); - - - final EventLoopGroup boss; - final EventLoopGroup work; - - if (OS.isAndroid()) { - // android ONLY supports OIO (not NIO) - boss = new OioEventLoopGroup(1, new NamedThreadFactory(threadName + "-boss", threadGroup)); - work = new OioEventLoopGroup(WORKER_THREAD_POOL_SIZE, new NamedThreadFactory(threadName, threadGroup)); - } - else if (OS.isLinux() && NativeLibrary.isAvailable()) { - // epoll network stack is MUCH faster (but only on linux) - boss = new EpollEventLoopGroup(1, new NamedThreadFactory(threadName + "-boss", threadGroup)); - work = new EpollEventLoopGroup(WORKER_THREAD_POOL_SIZE, new NamedThreadFactory(threadName, threadGroup)); - } - else if (OS.isMacOsX() && NativeLibrary.isAvailable()) { - // KQueue network stack is MUCH faster (but only on macosx) - boss = new KQueueEventLoopGroup(1, new NamedThreadFactory(threadName + "-boss", threadGroup)); - work = new KQueueEventLoopGroup(WORKER_THREAD_POOL_SIZE, new NamedThreadFactory(threadName, threadGroup)); - } - else { - // sometimes the native libraries cannot be loaded, so fall back to NIO - boss = new NioEventLoopGroup(1, new NamedThreadFactory(threadName + "-boss", threadGroup)); - work = new NioEventLoopGroup(WORKER_THREAD_POOL_SIZE, new NamedThreadFactory(threadName, threadGroup)); - } - - manageForShutdown(boss); - manageForShutdown(work); - - - tcpBootstrap = new ServerBootstrap(); - udpBootstrap = new Bootstrap(); - - - if (OS.isAndroid()) { - // android ONLY supports OIO (not NIO) - tcpBootstrap.channel(OioServerSocketChannel.class); - } - else if (OS.isLinux() && NativeLibrary.isAvailable()) { - // epoll network stack is MUCH faster (but only on linux) - tcpBootstrap.channel(EpollServerSocketChannel.class); - } - else if (OS.isMacOsX() && NativeLibrary.isAvailable()) { - // KQueue network stack is MUCH faster (but only on macosx) - tcpBootstrap.channel(KQueueServerSocketChannel.class); - } - else { - tcpBootstrap.channel(NioServerSocketChannel.class); - } - - // TODO: If we use netty for an HTTP server, - // Beside the usual ChannelOptions the Native Transport allows to enable TCP_CORK which may come in handy if you implement a HTTP Server. - - tcpBootstrap.group(boss, work) - .option(ChannelOption.SO_BACKLOG, backlogConnectionCount) - .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) - .childOption(ChannelOption.SO_KEEPALIVE, true) - .option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(EndPoint.WRITE_BUFF_LOW, EndPoint.WRITE_BUFF_HIGH)) - .childHandler(dnsServerHandler); - - // have to check options.host for "0.0.0.0". we don't bind to "0.0.0.0", we bind to "null" to get the "any" address! - if (hostName.equals("0.0.0.0")) { - tcpBootstrap.localAddress(tcpPort); - } - else { - tcpBootstrap.localAddress(hostName, tcpPort); - } - - - // android screws up on this!! - tcpBootstrap.option(ChannelOption.TCP_NODELAY, !OS.isAndroid()) - .childOption(ChannelOption.TCP_NODELAY, !OS.isAndroid()); - - - if (OS.isAndroid()) { - // android ONLY supports OIO (not NIO) - udpBootstrap.channel(OioDatagramChannel.class); - } - else if (OS.isLinux() && NativeLibrary.isAvailable()) { - // epoll network stack is MUCH faster (but only on linux) - udpBootstrap.channel(EpollDatagramChannel.class); - } - else if (OS.isMacOsX() && NativeLibrary.isAvailable()) { - // KQueue network stack is MUCH faster (but only on macosx) - udpBootstrap.channel(KQueueDatagramChannel.class); - } - else { - udpBootstrap.channel(NioDatagramChannel.class); - } - - udpBootstrap.group(work) - .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) - .option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(EndPoint.WRITE_BUFF_LOW, EndPoint.WRITE_BUFF_HIGH)) - - // not binding to specific address, since it's driven by TCP, and that can be bound to a specific address - .localAddress(udpPort) // if you bind to a specific interface, Linux will be unable to receive broadcast packets! - .handler(dnsServerHandler); - } - - @Override - protected - void stopExtraActions() { - dnsServerHandler.stop(); - } - - /** - * Binds the server to the configured, underlying protocols. - *

- * This method will also BLOCK until the stop method is called, and if you want to continue running code after this method invocation, - * bind should be called in a separate, non-daemon thread. - */ - public - void bind() { - bind(true); - } - - /** - * Binds the server to the configured, underlying protocols. - *

- * This is a more advanced method, and you should consider calling bind() instead. - * - * @param blockUntilTerminate will BLOCK until the server stop method is called, and if you want to continue running code after this method - * invocation, bind should be called in a separate, non-daemon thread - or with false as the parameter. - */ - @SuppressWarnings("AutoBoxing") - public - void bind(boolean blockUntilTerminate) { - // make sure we are not trying to connect during a close or stop event. - // This will wait until we have finished starting up/shutting down. - synchronized (shutdownInProgress) { - } - - - // The bootstraps will be accessed ONE AT A TIME, in this order! - ChannelFuture future; - - Logger logger2 = logger; - - - // TCP - // Wait until the connection attempt succeeds or fails. - // try { - // future = tcpBootstrap.bind(); - // future.await(); - // } catch (Exception e) { - // // String errorMessage = stopWithErrorMessage(logger2, - // // "Could not bind to address " + hostName + " TCP port " + tcpPort + - // // " on the server.", - // // e); - // // throw new IllegalArgumentException(errorMessage); - // throw new RuntimeException(); - // } - // - // if (!future.isSuccess()) { - // // String errorMessage = stopWithErrorMessage(logger2, - // // "Could not bind to address " + hostName + " TCP port " + tcpPort + - // // " on the server.", - // // future.cause()); - // // throw new IllegalArgumentException(errorMessage); - // throw new RuntimeException(); - // } - // - // // logger2.info("Listening on address {} at TCP port: {}", hostName, tcpPort); - // - // manageForShutdown(future); - - - // UDP - // Wait until the connection attempt succeeds or fails. - try { - future = udpBootstrap.bind(); - future.await(); - } catch (Exception e) { - String errorMessage = stopWithErrorMessage(logger2, - "Could not bind to address " + hostName + " UDP port " + udpPort + - " on the server.", - e); - throw new IllegalArgumentException(errorMessage); - } - - if (!future.isSuccess()) { - String errorMessage = stopWithErrorMessage(logger2, - "Could not bind to address " + hostName + " UDP port " + udpPort + - " on the server.", - future.cause()); - throw new IllegalArgumentException(errorMessage); - } - - // logger2.info("Listening on address {} at UDP port: {}", hostName, udpPort); - manageForShutdown(future); - - // we now BLOCK until the stop method is called. - // if we want to continue running code in the server, bind should be called in a separate, non-daemon thread. - if (blockUntilTerminate) { - waitForShutdown(); - } - } - - - /** - * Adds a domain name query result, so clients that request the domain name will get the ipAddress - * - * @param domainName the domain name to have results for - * @param ipAddresses the ip addresses (can be multiple) to return for the requested domain name - */ - public - void aRecord(final String domainName, final int dClass, final int ttl, final String... ipAddresses) { - Name name = DnsQuestion.createName(domainName, DnsRecordType.A); - - int length = ipAddresses.length; - ArrayList records = new ArrayList(length); - - for (int i = 0; i < length; i++) { - byte[] address = NetUtil.createByteArrayFromIpAddressString(ipAddresses[i]); - records.add(new ARecord(name, dClass, ttl, address)); - } - - dnsServerHandler.addARecord(name, records); - } -} diff --git a/src/dorkbox/network/dns/Compression.java b/src/dorkbox/network/dns/Compression.java deleted file mode 100644 index a396181a..00000000 --- a/src/dorkbox/network/dns/Compression.java +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns; - -import dorkbox.network.dns.records.DnsMessage; -import dorkbox.network.dns.utils.Options; - -/** - * DNS Name Compression object. - * - * @author Brian Wellington - * @see DnsMessage - * @see Name - */ - -public -class Compression { - - private static final int TABLE_SIZE = 17; - private static final int MAX_POINTER = 0x3FFF; - private Entry[] table; - private boolean verbose = Options.check("verbosecompression"); - - - private static - class Entry { - Name name; - int pos; - Entry next; - } - - /** - * Creates a new Compression object. - */ - public - Compression() { - table = new Entry[TABLE_SIZE]; - } - - /** - * Adds a compression entry mapping a name to a position in a message. - * - * @param pos The position at which the name is added. - * @param name The name being added to the message. - */ - public - void add(int pos, Name name) { - if (pos > MAX_POINTER) { - return; - } - int row = (name.hashCode() & 0x7FFFFFFF) % TABLE_SIZE; - Entry entry = new Entry(); - entry.name = name; - entry.pos = pos; - entry.next = table[row]; - table[row] = entry; - if (verbose) { - System.err.println("Adding " + name + " at " + pos); - } - } - - /** - * Retrieves the position of the given name, if it has been previously - * included in the message. - * - * @param name The name to find in the compression table. - * - * @return The position of the name, or -1 if not found. - */ - public - int get(Name name) { - int row = (name.hashCode() & 0x7FFFFFFF) % TABLE_SIZE; - int pos = -1; - for (Entry entry = table[row]; entry != null; entry = entry.next) { - if (entry.name.equals(name)) { - pos = entry.pos; - } - } - if (verbose) { - System.err.println("Looking for " + name + ", found " + pos); - } - return pos; - } - -} diff --git a/src/dorkbox/network/dns/DnsEnvelope.java b/src/dorkbox/network/dns/DnsEnvelope.java deleted file mode 100644 index 87caeece..00000000 --- a/src/dorkbox/network/dns/DnsEnvelope.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns; - -import java.io.IOException; -import java.net.InetSocketAddress; - -import dorkbox.network.dns.records.DnsMessage; -import io.netty.buffer.ByteBuf; -import io.netty.channel.AddressedEnvelope; - -/** - * - */ -public -class DnsEnvelope extends DnsMessage implements AddressedEnvelope { - - private InetSocketAddress localAddress; - private InetSocketAddress remoteAddress; - - public - DnsEnvelope() { - super(); - } - - - public - DnsEnvelope(final int id, final InetSocketAddress localAddress, final InetSocketAddress remoteAddress) { - super(id); - - this.localAddress = localAddress; - this.remoteAddress = remoteAddress; - } - - public - DnsEnvelope(final ByteBuf buffer, final InetSocketAddress localAddress, final InetSocketAddress remoteAddress) throws IOException { - super(buffer); - - this.localAddress = localAddress; - this.remoteAddress = remoteAddress; - } - - - public - DnsEnvelope(final DnsInput input, final InetSocketAddress localAddress, final InetSocketAddress remoteAddress) throws IOException { - super(input); - - this.localAddress = localAddress; - this.remoteAddress = remoteAddress; - } - - public - void setLocalAddress(final InetSocketAddress localAddress) { - this.localAddress = localAddress; - } - - public - void setRemoteAddress(final InetSocketAddress remoteAddress) { - this.remoteAddress = remoteAddress; - } - - @Override - public - DnsEnvelope content() { - return this; - } - - @Override - public final - InetSocketAddress sender() { - return localAddress; - } - - @Override - public final - InetSocketAddress recipient() { - return remoteAddress; - } - - - - @Override - public - DnsEnvelope touch() { - return (DnsEnvelope) super.touch(); - } - - @Override - public - DnsEnvelope touch(Object hint) { - return (DnsEnvelope) super.touch(hint); - } - - @Override - public - DnsEnvelope retain() { - return (DnsEnvelope) super.retain(); - } - - @Override - public - DnsEnvelope retain(int increment) { - return (DnsEnvelope) super.retain(increment); - } -} diff --git a/src/dorkbox/network/dns/DnsInput.java b/src/dorkbox/network/dns/DnsInput.java deleted file mode 100644 index 6139dbfa..00000000 --- a/src/dorkbox/network/dns/DnsInput.java +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns; - -import dorkbox.network.dns.exceptions.WireParseException; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; - -/** - * An class for parsing DNS messages. - * - * @author Brian Wellington - */ - -public -class DnsInput { - - private ByteBuf byteBuf; - private int savedActiveIndex = -1; - private boolean marked = false; - - /** - * Creates a new DnsInput - * - * @param input The byte array to read from - */ - public - DnsInput(byte[] input) { - byteBuf = Unpooled.wrappedBuffer(input); - } - - /** - * Creates a new DnsInput from the given {@link ByteBuf} - * - * @param byteBuf The ByteBuf - */ - public - DnsInput(ByteBuf byteBuf) { - this.byteBuf = byteBuf; - } - - /** - * Returns the current position, for reading only - */ - public - int readIndex() { - return byteBuf.readerIndex(); - } - - /** - * NOTE: "Active" restricts operations to a specific part of the buffer, defined by the current position + length. Operations that - * extend BEYOND this section are denied by virtue that we set the max readable length in the underlying ByteBuf. - * - * Marks the following bytes in the stream as active, and saves it's state (so it can be restored later) - * - * @param len The number of bytes in the active region. - * - * @throws IllegalArgumentException The number of bytes in the active region - * is longer than the remainder of the input. - */ - public - void setActive(int len) { - savedActiveIndex = byteBuf.writerIndex(); - - if (len > byteBuf.readableBytes()) { - throw new IllegalArgumentException("cannot set active " + "region past end of input"); - } - - byteBuf.writerIndex(byteBuf.readerIndex() + len); - } - - /** - * Restores the previously set active region. - */ - public - void restoreActive() { - if (savedActiveIndex > -1) { - byteBuf.writerIndex(savedActiveIndex); - savedActiveIndex = -1; - } - } - - /** - * Resets the current position of the input stream to the specified index, - * and clears the active region. - * - * @param index The position to continue parsing at. - * - * @throws IllegalArgumentException The index is not within the input. - */ - public - void jump(int index) { - if (index >= byteBuf.capacity()) { - throw new IllegalArgumentException("cannot jump past " + "end of input"); - } - byteBuf.readerIndex(index); - - restoreActive(); - } - - /** - * Saves the current state of the input stream. Both the current position and - * the end of the active region are saved. - * - * @throws IllegalArgumentException The index is not within the input. - */ - public - void save() { - marked = true; - byteBuf.markReaderIndex(); - } - - /** - * Restores the input stream to its state before the call to {@link #save}. - */ - public - void restore() { - if (!marked) { - throw new IllegalStateException("Not marked first"); - } - byteBuf.resetReaderIndex(); - } - - private - void require(int n) throws WireParseException { - if (n > remaining()) { - throw new WireParseException("end of input"); - } - } - - /** - * Returns the number of bytes that can be read from this stream before - * reaching the end. - */ - public - int remaining() { - return byteBuf.readableBytes(); - } - - /** - * Reads an unsigned 8 bit value from the stream, as an int. - * - * @return An unsigned 8 bit value. - * - * @throws WireParseException The end of the stream was reached. - */ - public - int readU8() throws WireParseException { - require(1); - return byteBuf.readUnsignedByte(); - } - - /** - * Reads an unsigned 16 bit value from the stream, as an int. - * - * @return An unsigned 16 bit value. - * - * @throws WireParseException The end of the stream was reached. - */ - public - int readU16() throws WireParseException { - require(2); - return byteBuf.readUnsignedShort(); - } - - /** - * Reads an unsigned 32 bit value from the stream, as a long. - * - * @return An unsigned 32 bit value. - * - * @throws WireParseException The end of the stream was reached. - */ - public - long readU32() throws WireParseException { - require(4); - return byteBuf.readUnsignedInt(); - } - - /** - * Reads a byte array of a specified length from the stream into an existing - * array. - * - * @param b The array to read into. - * @param off The offset of the array to start copying data into. - * @param len The number of bytes to copy. - * - * @throws WireParseException The end of the stream was reached. - */ - public - void readByteArray(byte[] b, int off, int len) throws WireParseException { - require(len); - byteBuf.readBytes(b, off, len); - } - - /** - * Reads a byte array of a specified length from the stream. - * - * @return The byte array. - * - * @throws WireParseException The end of the stream was reached. - */ - public - byte[] readByteArray(int len) throws WireParseException { - require(len); - byte[] out = new byte[len]; - byteBuf.readBytes(out, 0, len); - return out; - } - - /** - * Reads a byte array consisting of the remainder of the stream (or the - * active region, if one is set. - * - * @return The byte array. - */ - public - byte[] readByteArray() { - int len = remaining(); - byte[] out = new byte[len]; - byteBuf.readBytes(out, 0, len); - return out; - } - - /** - * Reads a counted string from the stream. A counted string is a one byte - * value indicating string length, followed by bytes of data. - * - * @return A byte array containing the string. - * - * @throws WireParseException The end of the stream was reached. - */ - public - byte[] readCountedString() throws WireParseException { - int len = readU8(); - return readByteArray(len); - } -} diff --git a/src/dorkbox/network/dns/DnsOutput.java b/src/dorkbox/network/dns/DnsOutput.java deleted file mode 100644 index 0854bef7..00000000 --- a/src/dorkbox/network/dns/DnsOutput.java +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; - -/** - * A class for rendering DNS messages. - * - * @author Brian Wellington - */ - - -public -class DnsOutput { - - private ByteBuf byteBuf; - private boolean marked = false; - - /** - * Create a new DnsOutput - */ - public - DnsOutput() { - this(32); - } - - /** - * Create a new DnsOutput with a specified size. - * - * @param size The initial size - */ - public - DnsOutput(int size) { - this(Unpooled.buffer(size)); - } - - /** - * Create a new DnsOutput with a specified ByteBuf. - * - * @param byteBuf The ByteBuf to use - */ - public - DnsOutput(ByteBuf byteBuf) { - this.byteBuf = byteBuf; - } - - /** - * Returns the current position. - */ - public - int current() { - return byteBuf.writerIndex(); - } - - /** - * Resets the current position of the output stream to the specified index. - * - * @param index The new current position. - * - * @throws IllegalArgumentException The index is not within the output. - */ - public - void jump(int index) { - if (index >= byteBuf.writerIndex()) { - // we haven't written data to this point yet, and the contract for jump() is that it can only jump to a PREVIOUSLY written spot - throw new IllegalArgumentException("Unable to jump to invalid position " + index + ". Max is " + byteBuf.writerIndex()); - } - - byteBuf.writerIndex(index); - } - - /** - * Saves the current state of the output stream. - * - * @throws IllegalArgumentException The index is not within the output. - */ - public - void save() { - marked = true; - byteBuf.markWriterIndex(); - } - - /** - * Restores the input stream to its state before the call to {@link #save}. - */ - public - void restore() { - if (!marked) { - throw new IllegalStateException("Not marked first"); - } - byteBuf.resetWriterIndex(); - marked = false; - } - - /** - * Writes an unsigned 8 bit value to the stream. - * - * @param val The value to be written - */ - public - void writeU8(int val) { - check(val, 8); - - byteBuf.ensureWritable(1); - byteBuf.writeByte(val); - } - - private - void check(long val, int bits) { - long max = 1; - max <<= bits; - if (val < 0 || val > max) { - throw new IllegalArgumentException(val + " out of range for " + bits + " bit value"); - } - } - - /** - * Writes an unsigned 16 bit value to the stream. - * - * @param val The value to be written - */ - public - void writeU16(int val) { - check(val, 16); - - byteBuf.ensureWritable(2); - byteBuf.writeShort(val); - } - - /** - * Writes an unsigned 16 bit value to the specified position in the stream. - * - * @param val The value to be written - * @param where The position to write the value. - */ - public - void writeU16At(int val, int where) { - check(val, 16); - - // save and set both the read/write index, otherwise if the read index is > write index, errors happen. - int saved = byteBuf.writerIndex(); - int readSaved = byteBuf.readerIndex(); - - byteBuf.setIndex(where, where); - byteBuf.ensureWritable(2); - byteBuf.writeShort(val); - - // put the read/write back to where it was (since this was an operation to write a value at a specific position) - byteBuf.writerIndex(saved); - byteBuf.readerIndex(readSaved); - } - - /** - * Writes an unsigned 32 bit value to the stream. - * - * @param val The value to be written - */ - public - void writeU32(long val) { - check(val, 32); - - byteBuf.ensureWritable(4); - byteBuf.writeInt((int) val); - } - - /** - * Writes a byte array to the stream. - * - * @param b The array to write. - */ - public - void writeByteArray(byte[] b) { - writeByteArray(b, 0, b.length); - } - - /** - * Writes a byte array to the stream. - * - * @param b The array to write. - * @param off The offset of the array to start copying data from. - * @param len The number of bytes to write. - */ - public - void writeByteArray(byte[] b, int off, int len) { - byteBuf.ensureWritable(len); - byteBuf.writeBytes(b, off, len); - } - - /** - * Writes a counted string from the stream. A counted string is a one byte - * value indicating string length, followed by bytes of data. - * - * @param s The string to write. - */ - public - void writeCountedString(byte[] s) { - if (s.length > 0xFF) { - throw new IllegalArgumentException("Invalid counted string"); - } - - byteBuf.ensureWritable(1 + s.length); - byteBuf.writeByte(s.length); - byteBuf.writeBytes(s, 0, s.length); - } - - /** - * Returns a byte array containing the current contents of the stream. - */ - public - byte[] toByteArray() { - byte[] out = new byte[byteBuf.writerIndex()]; - byteBuf.readBytes(out, 0, out.length); - return out; - } - - public - ByteBuf getByteBuf() { - return byteBuf; - } -} diff --git a/src/dorkbox/network/dns/DnsQuestion.java b/src/dorkbox/network/dns/DnsQuestion.java deleted file mode 100644 index fa344a9c..00000000 --- a/src/dorkbox/network/dns/DnsQuestion.java +++ /dev/null @@ -1,187 +0,0 @@ -package dorkbox.network.dns; - -import static io.netty.util.internal.ObjectUtil.checkNotNull; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.util.Locale; - -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsOpCode; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.constants.Flags; -import dorkbox.network.dns.records.DnsRecord; -import io.netty.channel.AddressedEnvelope; -import io.netty.util.internal.StringUtil; - -/** - * - */ -public -class DnsQuestion extends DnsEnvelope { - public static - DnsQuestion newResolveQuestion(final String inetHost, final int type, final boolean isRecursionDesired) { - return newQuestion(inetHost, type, isRecursionDesired, true); - } - - public static - DnsQuestion newQuery(final String inetHost, final int type, final boolean isRecursionDesired) { - return newQuestion(inetHost, type, isRecursionDesired, false); - } - - public static - Name createName(String hostName, final int type) { - // Convert to ASCII which will also check that the length is not too big. Throws null pointer if null. - // See: - // - https://github.com/netty/netty/issues/4937 - // - https://github.com/netty/netty/issues/4935 - hostName = hostNameAsciiFix(checkNotNull(hostName, "hostname")); - - if (hostName == null) { - // hostNameAsciiFix can throw a TextParseException if it fails to parse - return null; - } - - hostName = hostName.toLowerCase(Locale.US); - - - // NOTE: have to make sure that the hostname is a FQDN name - hostName = DnsRecordType.ensureFQDN(type, hostName); - - try { - return Name.fromString(hostName); - } catch (Exception e) { - // Name.fromString may throw a TextParseException if it fails to parse - return null; - } - } - - - private static - DnsQuestion newQuestion(final String inetHost, final int type, final boolean isRecursionDesired, boolean isResolveQuestion) { - - Name name = createName(inetHost, type); - - try { - DnsRecord questionRecord = DnsRecord.newRecord(name, type, DnsClass.IN); - DnsQuestion question = new DnsQuestion(isResolveQuestion); - question.getHeader() - .setOpcode(DnsOpCode.QUERY); - - if (isRecursionDesired) { - question.getHeader() - .setFlag(Flags.RD); - } - question.addRecord(questionRecord, DnsSection.QUESTION); - - // keep the question around so we can compare the response to it. - question.retain(); - - return question; - } catch (Exception e) { - e.printStackTrace(); - } - - return null; - } - - public static - String hostNameAsciiFix(String inetHost) { - try { - String hostName = java.net.IDN.toASCII(inetHost); // can throw IllegalArgumentException - - // Check for http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6894622 - if (StringUtil.endsWith(inetHost, '.') && !StringUtil.endsWith(hostName, '.')) { - return hostName + '.'; - } - - return hostName; - } catch (Exception e) { - // java.net.IDN.toASCII(...) may throw an IllegalArgumentException if it fails to parse the hostname - } - - return null; - } - - - - private final boolean isResolveQuestion; - - - /** - * Creates a new instance. - * - * @param isResolveQuestion true if it's a resolve question, which means we ALSO are going to keep resolving names until we get an IP - * address. - */ - private - DnsQuestion(final boolean isResolveQuestion) { - super(); - - this.isResolveQuestion = isResolveQuestion; - } - - public - boolean isResolveQuestion() { - return isResolveQuestion; - } - - public - void init(int id, InetSocketAddress recipient) { - getHeader().setID(id); - setRemoteAddress(recipient); - } - - @Override - public - int hashCode() { - int hashCode = super.hashCode(); - if (sender() != null) { - hashCode = hashCode * 31 + sender().hashCode(); - } - if (recipient() != null) { - hashCode = hashCode * 31 + recipient().hashCode(); - } - return hashCode; - } - - @Override - public - boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (!super.equals(obj)) { - return false; - } - - if (!(obj instanceof AddressedEnvelope)) { - return false; - } - - @SuppressWarnings("unchecked") - final AddressedEnvelope that = (AddressedEnvelope) obj; - if (sender() == null) { - if (that.sender() != null) { - return false; - } - } - else if (!sender().equals(that.sender())) { - return false; - } - - if (recipient() == null) { - if (that.recipient() != null) { - return false; - } - } - else if (!recipient().equals(that.recipient())) { - return false; - } - - return true; - } -} - diff --git a/src/dorkbox/network/dns/DnsServerResponse.java b/src/dorkbox/network/dns/DnsServerResponse.java deleted file mode 100644 index 0b3627de..00000000 --- a/src/dorkbox/network/dns/DnsServerResponse.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns; - -import java.net.InetSocketAddress; -import java.net.SocketAddress; - -import dorkbox.network.dns.records.DnsMessage; -import io.netty.channel.AddressedEnvelope; -import io.netty.util.internal.UnstableApi; - -/** - * A {@link DnsServerResponse} implementation for UDP/IP. - */ -@UnstableApi -public -class DnsServerResponse extends DnsEnvelope { - - /** - * Creates a new instance. - * - * @param localAddress the address of the sender - * @param remoteAddress the address of the recipient - */ - public - DnsServerResponse(final DnsMessage dnsQuestion, InetSocketAddress localAddress, InetSocketAddress remoteAddress) { - super(dnsQuestion.getHeader() - .getID(), localAddress, remoteAddress); - - if (remoteAddress == null && localAddress == null) { - throw new NullPointerException("localAddress and remoteAddress"); - } - } - - @Override - public - int hashCode() { - int hashCode = super.hashCode(); - if (sender() != null) { - hashCode = hashCode * 31 + sender().hashCode(); - } - if (recipient() != null) { - hashCode = hashCode * 31 + recipient().hashCode(); - } - return hashCode; - } - - @Override - public - boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (!super.equals(obj)) { - return false; - } - - if (!(obj instanceof AddressedEnvelope)) { - return false; - } - - @SuppressWarnings("unchecked") - final AddressedEnvelope that = (AddressedEnvelope) obj; - if (sender() == null) { - if (that.sender() != null) { - return false; - } - } - else if (!sender().equals(that.sender())) { - return false; - } - - if (recipient() == null) { - if (that.recipient() != null) { - return false; - } - } - else if (!recipient().equals(that.recipient())) { - return false; - } - - return true; - } -} diff --git a/src/dorkbox/network/dns/Mnemonic.java b/src/dorkbox/network/dns/Mnemonic.java deleted file mode 100644 index abd6d4b2..00000000 --- a/src/dorkbox/network/dns/Mnemonic.java +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns; - -import com.esotericsoftware.kryo.util.IntMap; - -import dorkbox.util.collections.ObjectIntMap; - -/** - * A utility class for converting between numeric codes and mnemonics - * for those codes. Mnemonics are case insensitive. - * - * @author Brian Wellington - */ -public -class Mnemonic { - - /** Strings are case-sensitive. */ - public static final int CASE_SENSITIVE = 1; - - /** Strings will be stored/searched for in uppercase. */ - public static final int CASE_UPPER = 2; - - /** Strings will be stored/searched for in lowercase. */ - public static final int CASE_LOWER = 3; - - private static final int INVALID_VALUE = -1; - - private ObjectIntMap strings; - private IntMap values; - - private String description; - private int wordcase; - private String prefix; - private int max; - private boolean numericok; - - /** - * Creates a new Mnemonic table. - * - * @param description A short description of the mnemonic to use when - * @param wordcase Whether to convert strings into uppercase, lowercase, - * or leave them unchanged. - * throwing exceptions. - */ - public - Mnemonic(String description, int wordcase) { - this.description = description; - this.wordcase = wordcase; - strings = new ObjectIntMap(); - values = new IntMap(); - max = Integer.MAX_VALUE; - } - - /** - * Sets the maximum numeric value - */ - public - void setMaximum(int max) { - this.max = max; - } - - /** - * Sets the prefix to use when converting to and from values that don't - * have mnemonics. - */ - public - void setPrefix(String prefix) { - this.prefix = sanitize(prefix); - } - - /* Converts a String to the correct case. */ - private - String sanitize(String str) { - if (wordcase == CASE_UPPER) { - return str.toUpperCase(); - } - else if (wordcase == CASE_LOWER) { - return str.toLowerCase(); - } - return str; - } - - /** - * Sets whether numeric values stored in strings are acceptable. - */ - public - void setNumericAllowed(boolean numeric) { - this.numericok = numeric; - } - - /** - * Defines the text representation of a numeric value. - * - * @param value The numeric value - * @param string The text string - */ - public - void add(int value, String string) { - check(value); - string = sanitize(string); - strings.put(string, value); - values.put(value, string); - } - - /** - * Checks that a numeric value is within the range [0..max] - */ - public - void check(int val) { - if (val < 0 || val > max) { - throw new IllegalArgumentException(description + " " + val + "is out of range"); - } - } - - /** - * Defines an additional text representation of a numeric value. This will - * be used by getValue(), but not getText(). - * - * @param value The numeric value - * @param string The text string - */ - public - void addAlias(int value, String string) { - check(value); - string = sanitize(string); - strings.put(string, value); - } - - /** - * Copies all mnemonics from one table into another. - * - * @param source The Mnemonic source to add from - * - * @throws IllegalArgumentException The wordcases of the Mnemonics do not - * match. - */ - public - void addAll(Mnemonic source) { - if (wordcase != source.wordcase) { - throw new IllegalArgumentException(source.description + ": wordcases do not match"); - } - - strings.putAll(source.strings); - values.putAll(source.values); - } - - /** - * Gets the text mnemonic corresponding to a numeric value. - * - * @param value The numeric value - * - * @return The corresponding text mnemonic. - */ - public - String getText(int value) { - check(value); - String str = values.get(value); - if (str != null) { - return str; - } - - str = Integer.toString(value); - if (prefix != null) { - return prefix + str; - } - return str; - } - - /** - * Gets the numeric value corresponding to a text mnemonic. - * - * @param str The text mnemonic - * - * @return The corresponding numeric value, or -1 if there is none - */ - public - int getValue(String str) { - str = sanitize(str); - int value = strings.get(str, INVALID_VALUE); - - if (value != INVALID_VALUE) { - return value; - } - if (prefix != null) { - if (str.startsWith(prefix)) { - int val = parseNumeric(str.substring(prefix.length())); - if (val >= 0) { - return val; - } - } - } - if (numericok) { - return parseNumeric(str); - } - - return INVALID_VALUE; - } - - private - int parseNumeric(String s) { - try { - int val = Integer.parseInt(s); - if (val >= 0 && val <= max) { - return val; - } - } catch (NumberFormatException ignored) { - } - - return INVALID_VALUE; - } -} diff --git a/src/dorkbox/network/dns/Name.java b/src/dorkbox/network/dns/Name.java deleted file mode 100644 index 5b7d2ecf..00000000 --- a/src/dorkbox/network/dns/Name.java +++ /dev/null @@ -1,1011 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns; - -import java.io.IOException; -import java.io.Serializable; -import java.text.DecimalFormat; - -import dorkbox.network.dns.exceptions.NameTooLongException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.network.dns.records.DNAMERecord; -import dorkbox.network.dns.utils.Options; - -/** - * A representation of a domain name. It may either be absolute (fully - * qualified) or relative. - * - * @author Brian Wellington - */ - -public -class Name implements Comparable, Serializable { - - private static final long serialVersionUID = -7257019940971525644L; - - private static final int LABEL_NORMAL = 0; - private static final int LABEL_COMPRESSION = 0xC0; - private static final int LABEL_MASK = 0xC0; - - /* The name data */ - private byte[] name; - - /* - * Effectively an 8 byte array, where the low order byte stores the number - * of labels and the 7 higher order bytes store per-label offsets. - */ - private long offsets; - - /* Precomputed hashcode. */ - private int hashcode; - - private static final byte[] emptyLabel = new byte[] {(byte) 0}; - private static final byte[] wildLabel = new byte[] {(byte) 1, (byte) '*'}; - - /** - * The root name - */ - public static final Name root; - - /** - * The root name - */ - public static final Name empty; - - /** - * The maximum length of a Name - */ - private static final int MAXNAME = 255; - - /** - * The maximum length of a label a Name - */ - private static final int MAXLABEL = 63; - - /** - * The maximum number of labels in a Name - */ - private static final int MAXLABELS = 128; - - /** - * The maximum number of cached offsets - */ - private static final int MAXOFFSETS = 7; - - /* Used for printing non-printable characters */ - private static final DecimalFormat byteFormat = new DecimalFormat(); - - /* Used to efficiently convert bytes to lowercase */ - private static final byte lowercase[] = new byte[256]; - - /* Used in wildcard names. */ - private static final Name wild; - - static { - byteFormat.setMinimumIntegerDigits(3); - for (int i = 0; i < lowercase.length; i++) { - if (i < 'A' || i > 'Z') { - lowercase[i] = (byte) i; - } - else { - lowercase[i] = (byte) (i - 'A' + 'a'); - } - } - root = new Name(); - root.appendSafe(emptyLabel, 0, 1); - empty = new Name(); - empty.name = new byte[0]; - wild = new Name(); - wild.appendSafe(wildLabel, 0, 1); - } - - private - Name() { - } - - private - void setoffset(int n, int offset) { - if (n >= MAXOFFSETS) { - return; - } - int shift = 8 * (7 - n); - offsets &= (~(0xFFL << shift)); - offsets |= ((long) offset << shift); - } - - private - int offset(int n) { - if (n == 0 && getlabels() == 0) { - return 0; - } - if (n < 0 || n >= getlabels()) { - throw new IllegalArgumentException("label out of range"); - } - if (n < MAXOFFSETS) { - int shift = 8 * (7 - n); - return ((int) (offsets >>> shift) & 0xFF); - } - else { - int pos = offset(MAXOFFSETS - 1); - for (int i = MAXOFFSETS - 1; i < n; i++) { - pos += (name[pos] + 1); - } - return (pos); - } - } - - private - void setlabels(int labels) { - offsets &= ~(0xFF); - offsets |= labels; - } - - private static - void copy(Name src, Name dst) { - if (src.offset(0) == 0) { - dst.name = src.name; - dst.offsets = src.offsets; - } - else { - int offset0 = src.offset(0); - int namelen = src.name.length - offset0; - int labels = src.labels(); - dst.name = new byte[namelen]; - System.arraycopy(src.name, offset0, dst.name, 0, namelen); - for (int i = 0; i < labels && i < MAXOFFSETS; i++) { - dst.setoffset(i, src.offset(i) - offset0); - } - dst.setlabels(labels); - } - } - - private - void append(byte[] array, int start, int n) throws NameTooLongException { - int length = (name == null ? 0 : (name.length - offset(0))); - int alength = 0; - for (int i = 0, pos = start; i < n; i++) { - int len = array[pos]; - if (len > MAXLABEL) { - throw new IllegalStateException("invalid label"); - } - len++; - pos += len; - alength += len; - } - int newlength = length + alength; - if (newlength > MAXNAME) { - throw new NameTooLongException(); - } - int labels = getlabels(); - int newlabels = labels + n; - if (newlabels > MAXLABELS) { - throw new IllegalStateException("too many labels"); - } - byte[] newname = new byte[newlength]; - if (length != 0) { - System.arraycopy(name, offset(0), newname, 0, length); - } - System.arraycopy(array, start, newname, length, alength); - name = newname; - for (int i = 0, pos = length; i < n; i++) { - setoffset(labels + i, pos); - pos += (newname[pos] + 1); - } - setlabels(newlabels); - } - - private static - TextParseException parseException(String str, String message) { - return new TextParseException("'" + str + "': " + message); - } - - private - void appendFromString(String fullName, byte[] array, int start, int n) throws TextParseException { - try { - append(array, start, n); - } catch (NameTooLongException e) { - throw parseException(fullName, "Name too long"); - } - } - - private - void appendSafe(byte[] array, int start, int n) { - try { - append(array, start, n); - } catch (NameTooLongException e) { - } - } - - /** - * Create a new name from a string and an origin. This does not automatically - * make the name absolute; it will be absolute if it has a trailing dot or an - * absolute origin is appended. - * - * @param s The string to be converted - * @param origin If the name is not absolute, the origin to be appended. - * - * @throws TextParseException The name is invalid. - */ - public - Name(String s, Name origin) throws TextParseException { - if (s.equals("")) { - throw parseException(s, "empty name"); - } - else if (s.equals("@")) { - if (origin == null) { - copy(empty, this); - } - else { - copy(origin, this); - } - return; - } - else if (s.equals(".")) { - copy(root, this); - return; - } - int labelstart = -1; - int pos = 1; - byte[] label = new byte[MAXLABEL + 1]; - boolean escaped = false; - int digits = 0; - int intval = 0; - boolean absolute = false; - for (int i = 0; i < s.length(); i++) { - byte b = (byte) s.charAt(i); - if (escaped) { - if (b >= '0' && b <= '9' && digits < 3) { - digits++; - intval *= 10; - intval += (b - '0'); - if (intval > 255) { - throw parseException(s, "bad escape"); - } - if (digits < 3) { - continue; - } - b = (byte) intval; - } - else if (digits > 0 && digits < 3) { - throw parseException(s, "bad escape"); - } - if (pos > MAXLABEL) { - throw parseException(s, "label too long"); - } - labelstart = pos; - label[pos++] = b; - escaped = false; - } - else if (b == '\\') { - escaped = true; - digits = 0; - intval = 0; - } - else if (b == '.') { - if (labelstart == -1) { - throw parseException(s, "invalid empty label"); - } - label[0] = (byte) (pos - 1); - appendFromString(s, label, 0, 1); - labelstart = -1; - pos = 1; - } - else { - if (labelstart == -1) { - labelstart = i; - } - if (pos > MAXLABEL) { - throw parseException(s, "label too long"); - } - label[pos++] = b; - } - } - if (digits > 0 && digits < 3) { - throw parseException(s, "bad escape"); - } - if (escaped) { - throw parseException(s, "bad escape"); - } - if (labelstart == -1) { - appendFromString(s, emptyLabel, 0, 1); - absolute = true; - } - else { - label[0] = (byte) (pos - 1); - appendFromString(s, label, 0, 1); - } - if (origin != null && !absolute) { - appendFromString(s, origin.name, origin.offset(0), origin.getlabels()); - } - } - - /** - * Create a new name from a string. This does not automatically make the name - * absolute; it will be absolute if it has a trailing dot. - * - * @param s The string to be converted - * - * @throws TextParseException The name is invalid. - */ - public - Name(String s) throws TextParseException { - this(s, null); - } - - /** - * Create a new name from a string. This does not automatically make the name - * absolute; it will be absolute if it has a trailing dot. This is identical - * to the constructor, except that it will avoid creating new objects in some - * cases. - * - * @param s The string to be converted - * - * @throws TextParseException The name is invalid. - */ - public static - Name fromString(String s) throws TextParseException { - return fromString(s, null); - } - - /** - * Create a new name from a string and an origin. This does not automatically - * make the name absolute; it will be absolute if it has a trailing dot or an - * absolute origin is appended. This is identical to the constructor, except - * that it will avoid creating new objects in some cases. - * - * @param s The string to be converted - * @param origin If the name is not absolute, the origin to be appended. - * - * @throws TextParseException The name is invalid. - */ - public static - Name fromString(String s, Name origin) throws TextParseException { - if (s.equals("@") && origin != null) { - return origin; - } - else if (s.equals(".")) { - return (root); - } - - return new Name(s, origin); - } - - /** - * Create a new name from a constant string. This should only be used when - * the name is known to be good - that is, when it is constant. - * - * @param s The string to be converted - * - * @throws IllegalArgumentException The name is invalid. - */ - public static - Name fromConstantString(String s) { - try { - return fromString(s, null); - } catch (TextParseException e) { - throw new IllegalArgumentException("Invalid name '" + s + "'"); - } - } - - /** - * Create a new name from DNS a wire format message - * - * @param in A stream containing the DNS message which is currently - * positioned at the start of the name to be read. - */ - public - Name(DnsInput in) throws WireParseException { - int len, pos; - boolean done = false; - byte[] label = new byte[MAXLABEL + 1]; - boolean savedState = false; - - while (!done) { - len = in.readU8(); - switch (len & LABEL_MASK) { - case LABEL_NORMAL: - if (getlabels() >= MAXLABELS) { - throw new WireParseException("too many labels"); - } - if (len == 0) { - append(emptyLabel, 0, 1); - done = true; - } - else { - label[0] = (byte) len; - in.readByteArray(label, 1, len); - append(label, 0, 1); - } - break; - case LABEL_COMPRESSION: - pos = in.readU8(); - pos += ((len & ~LABEL_MASK) << 8); - if (Options.check("verbosecompression")) { - System.err.println("currently " + in.readIndex() + ", pointer to " + pos); - } - - if (pos >= in.readIndex() - 2) { - throw new WireParseException("bad compression"); - } - if (!savedState) { - in.save(); - savedState = true; - } - in.jump(pos); - if (Options.check("verbosecompression")) { - System.err.println("current name '" + this + "', seeking to " + pos); - } - break; - default: - throw new WireParseException("bad label type"); - } - } - if (savedState) { - in.restore(); - } - } - - /** - * Create a new name from DNS wire format - * - * @param b A byte array containing the wire format of the name. - */ - public - Name(byte[] b) throws IOException { - this(new DnsInput(b)); - } - - /** - * Create a new name by removing labels from the beginning of an existing Name - * - * @param src An existing Name - * @param n The number of labels to remove from the beginning in the copy - */ - public - Name(Name src, int n) { - int slabels = src.labels(); - if (n > slabels) { - throw new IllegalArgumentException("attempted to remove too " + "many labels"); - } - name = src.name; - setlabels(slabels - n); - for (int i = 0; i < MAXOFFSETS && i < slabels - n; i++) { - setoffset(i, src.offset(i + n)); - } - } - - /** - * Creates a new name by concatenating two existing names. - * - * @param prefix The prefix name. - * @param suffix The suffix name. - * - * @return The concatenated name. - * - * @throws NameTooLongException The name is too long. - */ - public static - Name concatenate(Name prefix, Name suffix) throws NameTooLongException { - if (prefix.isAbsolute()) { - return (prefix); - } - Name newname = new Name(); - copy(prefix, newname); - newname.append(suffix.name, suffix.offset(0), suffix.getlabels()); - return newname; - } - - /** - * If this name is a subdomain of origin, return a new name relative to - * origin with the same value. Otherwise, return the existing name. - * - * @param origin The origin to remove. - * - * @return The possibly relativized name. - */ - public - Name relativize(Name origin) { - if (origin == null || !subdomain(origin)) { - return this; - } - Name newname = new Name(); - copy(this, newname); - int length = length() - origin.length(); - int labels = newname.labels() - origin.labels(); - newname.setlabels(labels); - newname.name = new byte[length]; - System.arraycopy(name, offset(0), newname.name, 0, length); - return newname; - } - - /** - * Generates a new Name with the first n labels are removed - * - * @return The parent name - */ - public - Name parent(final int n) { - if (n < 1) { - throw new IllegalArgumentException("must remove 1 or more " + "labels"); - } - try { - Name newname = new Name(); - newname.append(name, offset(n), getlabels() - n); - return newname; - } catch (NameTooLongException e) { - throw new IllegalStateException("Name.subdomain: concatenate failed"); - } - } - - /** - * Generates a new Name with the first n labels replaced by a wildcard - * - * @return The wildcard name - */ - public - Name wild(int n) { - if (n < 1) { - throw new IllegalArgumentException("must replace 1 or more " + "labels"); - } - try { - Name newname = new Name(); - copy(wild, newname); - newname.append(name, offset(n), getlabels() - n); - return newname; - } catch (NameTooLongException e) { - throw new IllegalStateException("Name.wild: concatenate failed"); - } - } - - /** - * Returns a canonicalized version of the Name (all lowercase). This may be - * the same name, if the input Name is already canonical. - */ - public - Name canonicalize() { - boolean canonical = true; - for (int i = 0; i < name.length; i++) { - if (lowercase[name[i] & 0xFF] != name[i]) { - canonical = false; - break; - } - } - if (canonical) { - return this; - } - - Name newname = new Name(); - newname.appendSafe(name, offset(0), getlabels()); - for (int i = 0; i < newname.name.length; i++) { - newname.name[i] = lowercase[newname.name[i] & 0xFF]; - } - - return newname; - } - - /** - * Generates a new Name to be used when following a DNAME. - * - * @param dname The DNAME record to follow. - * - * @return The constructed name. - * - * @throws NameTooLongException The resulting name is too long. - */ - public - Name fromDNAME(DNAMERecord dname) throws NameTooLongException { - Name dnameowner = dname.getName(); - Name dnametarget = dname.getTarget(); - if (!subdomain(dnameowner)) { - return null; - } - - int plabels = labels() - dnameowner.labels(); - int plength = length() - dnameowner.length(); - int pstart = offset(0); - - int dlabels = dnametarget.labels(); - int dlength = dnametarget.length(); - - if (plength + dlength > MAXNAME) { - throw new NameTooLongException(); - } - - Name newname = new Name(); - newname.setlabels(plabels + dlabels); - newname.name = new byte[plength + dlength]; - System.arraycopy(name, pstart, newname.name, 0, plength); - System.arraycopy(dnametarget.name, 0, newname.name, plength, dlength); - - for (int i = 0, pos = 0; i < MAXOFFSETS && i < plabels + dlabels; i++) { - newname.setoffset(i, pos); - pos += (newname.name[pos] + 1); - } - return newname; - } - - /** - * Is this name a wildcard? - */ - public - boolean isWild() { - if (labels() == 0) { - return false; - } - return (name[0] == (byte) 1 && name[1] == (byte) '*'); - } - - /** - * The number of labels in the name. - */ - public - int labels() { - return getlabels(); - } - - private - int getlabels() { - return (int) (offsets & 0xFF); - } - - /** - * Is this name absolute? - */ - public - boolean isAbsolute() { - int nlabels = labels(); - if (nlabels == 0) { - return false; - } - return name[offset(nlabels - 1)] == 0; - } - - /** - * The length of the name. - */ - public - short length() { - if (getlabels() == 0) { - return 0; - } - return (short) (name.length - offset(0)); - } - - /** - * Is the current Name a subdomain of the specified name? - */ - public - boolean subdomain(Name domain) { - int labels = labels(); - int dlabels = domain.labels(); - if (dlabels > labels) { - return false; - } - if (dlabels == labels) { - return equals(domain); - } - return domain.equals(name, offset(labels - dlabels)); - } - - private - String byteString(byte[] array, int pos) { - StringBuilder sb = new StringBuilder(); - int len = array[pos++]; - - for (int i = pos; i < pos + len; i++) { - int b = array[i] & 0xFF; - if (b <= 0x20 || b >= 0x7f) { - sb.append('\\'); - sb.append(byteFormat.format(b)); - } - else if (b == '"' || b == '(' || b == ')' || b == '.' || b == ';' || b == '\\' || b == '@' || b == '$') { - sb.append('\\'); - sb.append((char) b); - } - else { - sb.append((char) b); - } - } - - return sb.toString(); - } - - /** - * Convert a Name to a String - * - * @param omitFinalDot If true, and the name is absolute, omit the final dot. - * - * @return The representation of this name as a (printable) String. - */ - public - String toString(boolean omitFinalDot) { - int labels = labels(); - if (labels == 0) { - return "@"; - } - else if (labels == 1 && name[offset(0)] == 0) { - return "."; - } - StringBuilder sb = new StringBuilder(); - - for (int i = 0, pos = offset(0); i < labels; i++) { - int len = name[pos]; - if (len > MAXLABEL) { - throw new IllegalStateException("invalid label"); - } - if (len == 0) { - if (!omitFinalDot) { - sb.append('.'); - } - break; - } - if (i > 0) { - sb.append('.'); - } - sb.append(byteString(name, pos)); - pos += (1 + len); - } - - return sb.toString(); - } - - /** - * Retrieve the nth label of a Name. This makes a copy of the label; changing - * this does not change the Name. - * - * @param n The label to be retrieved. The first label is 0. - */ - public - byte[] getLabel(int n) { - int pos = offset(n); - byte len = (byte) (name[pos] + 1); - byte[] label = new byte[len]; - System.arraycopy(name, pos, label, 0, len); - return label; - } - - /** - * Convert the nth label in a Name to a String - * - * @param n The label to be converted to a (printable) String. The first - * label is 0. - */ - public - String getLabelString(int n) { - int pos = offset(n); - return byteString(name, pos); - } - - /** - * Emit a Name in DNS wire format - * - * @param out The output stream containing the DNS message. - * @param c The compression context, or null of no compression is desired. - * - * @throws IllegalArgumentException The name is not absolute. - */ - public - void toWire(DnsOutput out, Compression c) { - if (!isAbsolute()) { - throw new IllegalArgumentException("toWire() called on " + "non-absolute name"); - } - - int labels = labels(); - for (int i = 0; i < labels - 1; i++) { - Name tname; - if (i == 0) { - tname = this; - } - else { - tname = new Name(this, i); - } - int pos = -1; - if (c != null) { - pos = c.get(tname); - } - if (pos >= 0) { - pos |= (LABEL_MASK << 8); - out.writeU16(pos); - return; - } - else { - if (c != null) { - c.add(out.current(), tname); - } - int off = offset(i); - out.writeByteArray(name, off, name[off] + 1); - } - } - out.writeU8(0); - } - - /** - * Emit a Name in DNS wire format - * - * @throws IllegalArgumentException The name is not absolute. - */ - public - byte[] toWire() { - DnsOutput out = new DnsOutput(); - toWire(out, null); - return out.toByteArray(); - } - - /** - * Emit a Name in canonical DNS wire format (all lowercase) - * - * @param out The output stream to which the message is written. - */ - public - void toWireCanonical(DnsOutput out) { - byte[] b = toWireCanonical(); - out.writeByteArray(b); - } - - /** - * Emit a Name in canonical DNS wire format (all lowercase) - * - * @return The canonical form of the name. - */ - public - byte[] toWireCanonical() { - int labels = labels(); - if (labels == 0) { - return (new byte[0]); - } - byte[] b = new byte[name.length - offset(0)]; - for (int i = 0, spos = offset(0), dpos = 0; i < labels; i++) { - int len = name[spos]; - if (len > MAXLABEL) { - throw new IllegalStateException("invalid label"); - } - b[dpos++] = name[spos++]; - for (int j = 0; j < len; j++) { - b[dpos++] = lowercase[(name[spos++] & 0xFF)]; - } - } - return b; - } - - /** - * Emit a Name in DNS wire format - * - * @param out The output stream containing the DNS message. - * @param c The compression context, or null of no compression is desired. - * @param canonical If true, emit the name in canonicalized form - * (all lowercase). - * - * @throws IllegalArgumentException The name is not absolute. - */ - public - void toWire(DnsOutput out, Compression c, boolean canonical) { - if (canonical) { - toWireCanonical(out); - } - else { - toWire(out, c); - } - } - - private - boolean equals(byte[] b, int bpos) { - int labels = labels(); - for (int i = 0, pos = offset(0); i < labels; i++) { - if (name[pos] != b[bpos]) { - return false; - } - int len = name[pos++]; - bpos++; - if (len > MAXLABEL) { - throw new IllegalStateException("invalid label"); - } - for (int j = 0; j < len; j++) { - if (lowercase[(name[pos++] & 0xFF)] != lowercase[(b[bpos++] & 0xFF)]) { - return false; - } - } - } - return true; - } - - /** - * Computes a hashcode based on the value - */ - @Override - public - int hashCode() { - if (hashcode != 0) { - return (hashcode); - } - int code = 0; - for (int i = offset(0); i < name.length; i++) { - code += ((code << 3) + lowercase[(name[i] & 0xFF)]); - } - hashcode = code; - return hashcode; - } - - /** - * Are these two Names equivalent? - */ - @Override - public - boolean equals(Object arg) { - if (arg == this) { - return true; - } - if (arg == null || !(arg instanceof Name)) { - return false; - } - Name d = (Name) arg; - if (d.hashcode == 0) { - d.hashCode(); - } - if (hashcode == 0) { - hashCode(); - } - if (d.hashcode != hashcode) { - return false; - } - if (d.labels() != labels()) { - return false; - } - return equals(d.name, d.offset(0)); - } - - /** - * Convert a Name to a String - * - * @return The representation of this name as a (printable) String. - */ - @Override - public - String toString() { - return toString(false); - } - - /** - * Compares this Name to another Object. - * - * @param o The Object to be compared. - * - * @return The value 0 if the argument is a name equivalent to this name; - * a value less than 0 if the argument is less than this name in the canonical - * ordering, and a value greater than 0 if the argument is greater than this - * name in the canonical ordering. - * - * @throws ClassCastException if the argument is not a Name. - */ - @Override - public - int compareTo(Object o) { - Name arg = (Name) o; - - if (this == arg) { - return (0); - } - - int labels = labels(); - int alabels = arg.labels(); - int compares = labels > alabels ? alabels : labels; - - for (int i = 1; i <= compares; i++) { - int start = offset(labels - i); - int astart = arg.offset(alabels - i); - int length = name[start]; - int alength = arg.name[astart]; - for (int j = 0; j < length && j < alength; j++) { - int n = lowercase[(name[j + start + 1]) & 0xFF] - lowercase[(arg.name[j + astart + 1]) & 0xFF]; - if (n != 0) { - return (n); - } - } - if (length != alength) { - return (length - alength); - } - } - return (labels - alabels); - } - -} diff --git a/src/dorkbox/network/dns/clientHandlers/DatagramDnsQueryEncoder.java b/src/dorkbox/network/dns/clientHandlers/DatagramDnsQueryEncoder.java deleted file mode 100644 index a6d5350e..00000000 --- a/src/dorkbox/network/dns/clientHandlers/DatagramDnsQueryEncoder.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.clientHandlers; - -import java.net.InetSocketAddress; -import java.util.List; - -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.DnsQuestion; -import dorkbox.network.dns.records.DnsMessage; -import io.netty.buffer.ByteBuf; -import io.netty.channel.AddressedEnvelope; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.socket.DatagramPacket; -import io.netty.handler.codec.MessageToMessageEncoder; -import io.netty.util.internal.UnstableApi; - -/** - * Encodes an {@link AddressedEnvelope} of {@link DnsQuestion}} into a {@link DatagramPacket}. - */ -@UnstableApi -@ChannelHandler.Sharable -public -class DatagramDnsQueryEncoder extends MessageToMessageEncoder> { - - private final int maxPayloadSize; - - /** - * Creates a new encoder - */ - public - DatagramDnsQueryEncoder(int maxPayloadSize) { - this.maxPayloadSize = maxPayloadSize; - } - - @Override - protected - void encode(ChannelHandlerContext ctx, AddressedEnvelope in, List out) throws Exception { - - final InetSocketAddress recipient = in.recipient(); - final DnsMessage query = in.content(); - final ByteBuf buf = ctx.alloc() - .ioBuffer(maxPayloadSize); - - boolean success = false; - try { - DnsOutput dnsOutput = new DnsOutput(buf); - query.toWire(dnsOutput); - success = true; - } finally { - if (!success) { - buf.release(); - } - } - - out.add(new DatagramPacket(buf, recipient, null)); - } - - @Override - public - void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) throws Exception { - cause.printStackTrace(); - } -} diff --git a/src/dorkbox/network/dns/clientHandlers/DatagramDnsResponseDecoder.java b/src/dorkbox/network/dns/clientHandlers/DatagramDnsResponseDecoder.java deleted file mode 100644 index f6efa7b3..00000000 --- a/src/dorkbox/network/dns/clientHandlers/DatagramDnsResponseDecoder.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.clientHandlers; - -import java.util.List; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.network.dns.records.Header; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.socket.DatagramPacket; -import io.netty.handler.codec.MessageToMessageDecoder; -import io.netty.util.internal.UnstableApi; - -/** - * Decodes a {@link DatagramPacket} into a {@link DnsResponse}. - */ -@UnstableApi -@ChannelHandler.Sharable -public -class DatagramDnsResponseDecoder extends MessageToMessageDecoder { - - /** - * Creates a new DNS Response decoder - */ - public - DatagramDnsResponseDecoder() { - } - - @Override - protected - void decode(ChannelHandlerContext ctx, DatagramPacket packet, List out) throws Exception { - final ByteBuf buf = packet.content(); - - // Check that the response is long enough. - if (buf.readableBytes() < Header.LENGTH) { - throw new WireParseException("invalid DNS header - " + "too short"); - } - - DnsInput dnsInput = new DnsInput(buf); - DnsResponse dnsMessage = new DnsResponse(dnsInput, packet.sender(), packet.recipient()); - out.add(dnsMessage); - } -} diff --git a/src/dorkbox/network/dns/clientHandlers/DnsResponse.java b/src/dorkbox/network/dns/clientHandlers/DnsResponse.java deleted file mode 100644 index 8f2bdd5d..00000000 --- a/src/dorkbox/network/dns/clientHandlers/DnsResponse.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.clientHandlers; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.SocketAddress; - -import dorkbox.network.dns.DnsEnvelope; -import dorkbox.network.dns.DnsInput; -import io.netty.channel.AddressedEnvelope; -import io.netty.util.internal.UnstableApi; - -/** - * A {@link DnsResponse} implementation for UDP/IP. - */ -@UnstableApi -public -class DnsResponse extends DnsEnvelope { - - /** - * Creates a new instance. - * - * @param localAddress the address of the sender - * @param remoteAddress the address of the recipient - */ - public - DnsResponse(final DnsInput dnsInput, InetSocketAddress localAddress, InetSocketAddress remoteAddress) throws IOException { - super(dnsInput, localAddress, remoteAddress); - - if (remoteAddress == null && localAddress == null) { - throw new NullPointerException("localAddress and remoteAddress"); - } - } - - @Override - public - int hashCode() { - int hashCode = super.hashCode(); - if (sender() != null) { - hashCode = hashCode * 31 + sender().hashCode(); - } - if (recipient() != null) { - hashCode = hashCode * 31 + recipient().hashCode(); - } - return hashCode; - } - - @Override - public - boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (!super.equals(obj)) { - return false; - } - - if (!(obj instanceof AddressedEnvelope)) { - return false; - } - - @SuppressWarnings("unchecked") - final AddressedEnvelope that = (AddressedEnvelope) obj; - if (sender() == null) { - if (that.sender() != null) { - return false; - } - } - else if (!sender().equals(that.sender())) { - return false; - } - - if (recipient() == null) { - if (that.recipient() != null) { - return false; - } - } - else if (!recipient().equals(that.recipient())) { - return false; - } - - return true; - } -} diff --git a/src/dorkbox/network/dns/constants/DnsClass.java b/src/dorkbox/network/dns/constants/DnsClass.java deleted file mode 100644 index dce2cf40..00000000 --- a/src/dorkbox/network/dns/constants/DnsClass.java +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.constants; - -import dorkbox.network.dns.Mnemonic; -import dorkbox.network.dns.exceptions.InvalidDClassException; - -/** - * Constants and functions relating to DNS classes. This is called DnsClass to avoid confusion with Class. - * - * @author Brian Wellington - */ -public final -class DnsClass { - - /** - * Internet DNS resource record class: {@code IN} - */ - public static final int IN = 1; - - /** - * Computer Science Network network DNS resource record class: {@code CSNET}. It was never installed as a top-level domain - * in the Domain Name System, but parsed in the message routing logic of mail transport agents (MTA). It was introduced in 1985. - */ - public static final int CS = 2; - - /** - * Computer Science Network network DNS resource record class: {@code CSNET}. It was never installed as a top-level domain - * in the Domain Name System, but parsed in the message routing logic of mail transport agents (MTA). It was introduced in 1985. - */ - public static final int CSNET = 2; - - /** - * Chaos network DNS resource record class: {@code CH} (MIT) - */ - public static final int CH = 3; - - /** - * Chaos network DNS resource record class: {@code CHAOS} (MIT, alternate name) - */ - public static final int CHAOS = 3; - - /** - * Hesiod DNS resource record class: {@code HS} (MIT) - */ - public static final int HS = 4; - - /** - * Hesiod DNS resource record class: {@code HESIOD} (MIT, alternate name) - */ - public static final int HESIOD = 4; - - /** - * Special value used in dynamic update messages - */ - public static final int NONE = 254; - - /** - * Matches any class - */ - public static final int ANY = 255; - - - - private static Mnemonic classes = new DClassMnemonic(); - - - private static - class DClassMnemonic extends Mnemonic { - DClassMnemonic() { - super("DnsClass", CASE_UPPER); - setPrefix("CLASS"); - } - - @Override - public - void check(int val) { - DnsClass.check(val); - } - } - - - static { - classes.add(IN, "IN"); - classes.add(CS, "CS"); - classes.addAlias(CSNET, "CSNET"); - classes.add(CH, "CH"); - classes.addAlias(CH, "CHAOS"); - classes.add(HS, "HS"); - classes.addAlias(HS, "HESIOD"); - classes.add(NONE, "NONE"); - classes.add(ANY, "ANY"); - } - - private - DnsClass() {} - - /** - * Checks that a numeric DnsClass is valid. - * - * @throws InvalidDClassException The class is out of range. - */ - public static - void check(int i) { - if (i < 0 || i > 0xFFFF) { - throw new InvalidDClassException(i); - } - } - - /** - * Converts a numeric DnsClass into a String - * - * @return The canonical string representation of the class - * - * @throws InvalidDClassException The class is out of range. - */ - public static - String string(int i) { - return classes.getText(i); - } - - /** - * Converts a String representation of a DnsClass into its numeric value - * - * @return The class code, or -1 on error. - */ - public static - int value(String s) { - return classes.getValue(s); - } - -} diff --git a/src/dorkbox/network/dns/constants/DnsOpCode.java b/src/dorkbox/network/dns/constants/DnsOpCode.java deleted file mode 100644 index ad8918f6..00000000 --- a/src/dorkbox/network/dns/constants/DnsOpCode.java +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.constants; - -import dorkbox.network.dns.Mnemonic; - -/** - * Constants and functions relating to DNS opcodes - * - * @author Brian Wellington - */ - -public final -class DnsOpCode { - - /** - * A standard query - */ - public static final int QUERY = 0; - - /** - * An inverse query (deprecated) - */ - public static final int IQUERY = 1; - - /** - * A server status request (not used) - */ - public static final int STATUS = 2; - - /** - * A message from a primary to a secondary server to initiate a zone transfer - */ - public static final int NOTIFY = 4; - - /** - * A dynamic update message - */ - public static final int UPDATE = 5; - - private static Mnemonic opcodes = new Mnemonic("DNS DnsOpCode", Mnemonic.CASE_UPPER); - - static { - opcodes.setMaximum(0xF); - opcodes.setPrefix("RESERVED"); - opcodes.setNumericAllowed(true); - - opcodes.add(QUERY, "QUERY"); - opcodes.add(IQUERY, "IQUERY"); - opcodes.add(STATUS, "STATUS"); - opcodes.add(NOTIFY, "NOTIFY"); - opcodes.add(UPDATE, "UPDATE"); - } - - private - DnsOpCode() {} - - /** - * Converts a numeric DnsOpCode into a String - */ - public static - String string(int i) { - return opcodes.getText(i); - } - - /** - * Converts a String representation of an DnsOpCode into its numeric value - */ - public static - int value(String s) { - return opcodes.getValue(s); - } -} diff --git a/src/dorkbox/network/dns/constants/DnsRecordType.java b/src/dorkbox/network/dns/constants/DnsRecordType.java deleted file mode 100644 index f4699b9a..00000000 --- a/src/dorkbox/network/dns/constants/DnsRecordType.java +++ /dev/null @@ -1,610 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.constants; - -import dorkbox.network.dns.Mnemonic; -import dorkbox.network.dns.exceptions.InvalidTypeException; -import dorkbox.network.dns.records.DnsRecord; -import dorkbox.network.dns.records.DnsTypeProtoAssignment; -import dorkbox.util.collections.IntMap; -import io.netty.util.internal.StringUtil; - -/** - * Constants and functions relating to DNS Types - * - * @author Brian Wellington - */ - -public final -class DnsRecordType { - - /** - * Address record RFC 1035 Returns a 32-bit IPv4 address, most commonly used - * to map hostnames to an IP address of the host, but also used for DNSBLs, - * storing subnet masks in RFC 1101, etc. - */ - public static final int A = 1; - - /** - * Name server record RFC 1035 Delegates a DNS zone to use the given - * authoritative name servers - */ - public static final int NS = 2; - - /** - * Mail destination. MD specifies the final destination to which a message addressed to a given domain name should be delivered - * (Obsolete, as it's behavior has been replaced by MX) - */ - @Deprecated - public static final int MD = 3; - - /** - * Mail forwarder. MF specifies a host that would forward mail on to the eventual destination, should that destination be unreachable. - * (Obsolete, as it's behavior has been replaced by MX) - */ - @Deprecated - public static final int MF = 4; - - /** - * Canonical name (alias) record RFC 1035 Alias of one name to another: the DNS - * lookup will continue by retrying the lookup with the new name. - */ - public static final int CNAME = 5; - - /** - * Start of [a zone of] authority record RFC 1035 and RFC 2308 Specifies - * authoritative information about a DNS zone, including the primary name - * server, the email of the domain administrator, the domain serial number, - * and several timers relating to refreshing the zone. - */ - public static final int SOA = 6; - - /** - * Mailbox domain name RFC 1035. EXPERIMENTAL. A which specifies a host which has the - * specified mailbox. - */ - public static final int MB = 7; - - /** - * Mail group member RFC 1035. EXPERIMENTAL. A which specifies a mailbox which is a - * member of the mail group specified by the domain name. MG records cause no additional section processing. - */ - public static final int MG = 8; - - /** - * Mail rename name RFC 1035. EXPERIMENTAL. A which specifies a mailbox which is the - * proper rename of the specified mailbox. - */ - public static final int MR = 9; - - /** - * Null record RFC 1035. EXPERIMENTAL. Anything at all may be in the RDATA field so long as it is 65535 octets - * or less - */ - public static final int NULL = 10; - - /** - * The WKS record RFC 1035 is used to describe the well known services supported by - * a particular protocol on a particular internet address. - */ - public static final int WKS = 11; - - /** - * Pointer record RFC 1035 Pointer to a canonical name. Unlike a CNAME, DNS - * processing does NOT proceed, just the name is returned. The most common - * use is for implementing reverse DNS lookups, but other uses include such - * things as DNS-SD. - */ - public static final int PTR = 12; - - /** - * Host information HINFO RFC 1035. records are used to acquire general information about a host. The - * main use is for protocols such as FTP that can use special procedures when talking between machines - * or operating systems of the same type. - */ - public static final int HINFO = 13; - - /** - * Mailbox or mail list information RFC 1035. EXPERIMENTAL. MINFO records cause no additional section processing. Although these - * records can be associated with a simple mailbox, they are usually used with a mailing list. - */ - public static final int MINFO = 14; - - /** - * Mail exchange (routing) record RFC 1035 Maps a domain name to a list of message transfer agents for that domain. - */ - public static final int MX = 15; - - /** - * Text record RFC 1035 Originally for arbitrary human-readable text in a - * DNS record. Since the early 1990s, however, this record more often - * carries machine-readable data, such as specified by RFC 1464, - * opportunistic encryption, Sender Policy Framework, DKIM, DMARC DNS-SD, - * etc. - */ - public static final int TXT = 16; - - /** - * Responsible person record RFC 1183 Information about the responsible - * person(s) for the domain. Usually an email address with the @ replaced by - * a . - */ - public static final int RP = 17; - - /** - * AFS cell database record RFC 1183 Location of database servers of an AFS cell. - * This record is commonly used by AFS clients to contact AFS cells outside - * their local domain. A subtype of this record is used by the obsolete - * DCE/DFS file system. - */ - public static final int AFSDB = 18; - - /** - * X.25 calling address - */ - public static final int X25 = 19; - - /** - * ISDN calling address - */ - public static final int ISDN = 20; - - /** - * Router - */ - public static final int RT = 21; - - /** - * NSAP address - */ - public static final int NSAP = 22; - - /** - * Reverse NSAP address (deprecated) - */ - @Deprecated - public static final int NSAP_PTR = 23; - - /** - * Signature record RFC 2535 Signature record used in SIG(0) (RFC 2931) and - * TKEY (RFC 2930). RFC 3755 designated RRSIG as the replacement for SIG for - * use within DNSSEC. - */ - public static final int SIG = 24; - - /** - * key record RFC 2535 and RFC 2930 Used only for SIG(0) (RFC 2931) and TKEY - * (RFC 2930). RFC 3445 eliminated their use for application keys and - * limited their use to DNSSEC. RFC 3755 designates DNSKEY as the - * replacement within DNSSEC. RFC 4025 designates IPSECKEY as the - * replacement for use with IPsec. - */ - public static final int KEY = 25; - - /** - * X.400 mail mapping - */ - public static final int PX = 26; - - /** - * Geographical position (withdrawn) - */ - @Deprecated - public static final int GPOS = 27; - - /** - * IPv6 address record RFC 3596 Returns a 128-bit IPv6 address, most - * commonly used to map hostnames to an IP address of the host. - */ - public static final int AAAA = 28; - - /** - * Location record RFC 1876 Specifies a geographical location associated - * with a domain name. - */ - public static final int LOC = 29; - - /** - * Next valid name in zone - */ - public static final int NXT = 30; - - /** - * Endpoint identifier - */ - public static final int EID = 31; - - /** - * Nimrod locator - */ - public static final int NIMLOC = 32; - - /** - * Service selection locator RFC 2782 Generalized service location record, used for - * newer protocols instead of creating protocol-specific records such as MX. - */ - public static final int SRV = 33; - - /** - * ATM address - */ - public static final int ATMA = 34; - - /** - * Naming Authority Pointer record RFC 3403 Allows regular expression based - * rewriting of domain names which can then be used as URIs, further domain - * names to lookups, etc. - */ - public static final int NAPTR = 35; - - /** - * Key eXchanger record RFC 2230 Used with some cryptographic systems (not - * including DNSSEC) to identify a key management agent for the associated - * domain-name. Note that this has nothing to do with DNS Security. It is - * Informational status, rather than being on the IETF standards-track. It - * has always had limited deployment, but is still in use. - */ - public static final int KX = 36; - - /** - * Certificate record RFC 4398 Stores PKIX, SPKI, PGP, etc. - */ - public static final int CERT = 37; - - /** - * IPv6 address (experimental) - */ - public static final int A6 = 38; - - /** - * Delegation name record RFC 2672 DNAME creates an alias for a name and all - * its subnames, unlike CNAME, which aliases only the exact name in its - * label. Like the CNAME record, the DNS lookup will continue by retrying - * the lookup with the new name. This is also known as Non-terminal name redirection - */ - public static final int DNAME = 39; - - /** - * Options - contains EDNS metadata. Option record RFC 2671 This is a pseudo DNS - * record type needed to support EDNS. - */ - public static final int OPT = 41; - - /** - * Address Prefix List record RFC 3123 Specify lists of address ranges, e.g. - * in CIDR format, for various address families. Experimental. - */ - public static final int APL = 42; - - /** - * Delegation signer record RFC 4034 The record used to identify the DNSSEC - * signing key of a delegated zone. - */ - public static final int DS = 43; - - /** - * SSH Public Key Fingerprint record RFC 4255 Resource record for publishing - * SSH public host key fingerprints in the DNS System, in order to aid in - * verifying the authenticity of the host. RFC 6594 defines ECC SSH keys and - * SHA-256 hashes. See the IANA SSHFP RR parameters registry for details. - */ - public static final int SSHFP = 44; - - /** - * IPsec Key record RFC 4025 Key record that can be used with IPsec. - */ - public static final int IPSECKEY = 45; - - /** - * Resource Record Signature. DNSSEC signature record RFC 4034 Signature for a DNSSEC-secured record - * set. Uses the same format as the SIG record. - */ - public static final int RRSIG = 46; - - /** - * Next Secure Name. Next-Secure record RFC 4034 Part of DNSSEC, used to prove a name does not - * exist. Uses the same format as the (obsolete) NXT record. - */ - public static final int NSEC = 47; - - /** - * DNSSEC Key record RFC 4034 The key record used in DNSSEC. Uses the same - * format as the KEY record. - */ - public static final int DNSKEY = 48; - - /** - * Dynamic Host Configuration Protocol (DHCP) ID. DHCP identifier record RFC 4701 - * Used in conjunction with the FQDN option to DHCP. - */ - public static final int DHCID = 49; - - /** - * Next SECure, 3rd edition, RFC 5155. An extension to DNSSEC that allows proof - * of nonexistence for a name without permitting zonewalking. - */ - public static final int NSEC3 = 50; - - /** - * NSEC3 parameters record RFC 5155 Parameter record for use with NSEC3. - */ - public static final int NSEC3PARAM = 51; - - /** - * Transport Layer Security Authentication, draft-ietf-dane-protocol-23. - * TLSA certificate association record RFC 6698 A record for DNS-based - * Authentication of Named Entities (DANE). RFC 6698 defines The TLSA DNS - * resource record is used to associate a TLS server certificate or public - * key with the domain name where the record is found, thus forming a 'TLSA - * certificate association'. - */ - public static final int TLSA = 52; - - /** - * S/MIME cert association, draft-ietf-dane-smime - */ - public static final int SMIMEA = 53; - - - /** - * Host Identity Protocol record RFC 5205 Method of separating the end-point - * identifier and locator roles of IP addresses. - */ - public static final int HIP = 55; - - /** - * OpenPGP Key, RFC 7929 - */ - public static final int OPENPGPKEY = 61; - - /** - * Sender Policy Framework (experimental) record RFC 4408 Specified as part of the SPF - * protocol as an alternative to of storing SPF data in TXT records. Uses - * the same format as the earlier TXT record. - */ - public static final int SPF = 99; - - /** - * Transaction key - used to compute a shared secret or exchange a key. - * Secret key record RFC 2930 A method of providing keying material to be - * used with TSIG that is encrypted under the public key in an accompanying - * KEY RR.. - */ - public static final int TKEY = 249; - - /** - * Transaction Signature record RFC 2845 Can be used to authenticate dynamic - * updates as coming from an approved client, or to authenticate responses - * as coming from an approved recursive name server similar to DNSSEC. - */ - public static final int TSIG = 250; - - /** - * Incremental Zone Transfer record RFC 1996 Requests a zone transfer of the - * given zone but only differences from a previous serial number. This - * request may be ignored and a full (AXFR) sent in response if the - * authoritative server is unable to fulfill the request due to - * configuration or lack of required deltas. - */ - public static final int IXFR = 251; - - /** - * Authoritative Zone Transfer record RFC 1035 Transfer entire zone file - * from the master name server to secondary name servers. - */ - public static final int AXFR = 252; - - /** - * Transfer mailbox records - */ - public static final int MAILB = 253; - - /** - * Transfer mail agent records - */ - public static final int MAILA = 254; - - /** - * Matches any type - * - * All cached records RFC 1035 Returns all records of all types known to the - * name server. If the name server does not have any information on the - * name, the request will be forwarded on. The records returned may not be - * complete. For example, if there is both an A and an MX for a name, but - * the name server has only the A record cached, only the A record will be - * returned. Sometimes referred to as ANY, for example in Windows nslookup - * and Wireshark. - */ - public static final int ANY = 255; - - /** - * URI - * - * @see draft-faltstrom-uri-14 - */ - public static final int URI = 256; - - /** - * Certification Authority Authorization, RFC 6844. CA pinning, - * constraining acceptable CAs for a host/domain. - */ - public static final int CAA = 257; - - /** - * DNSSEC Trust Authorities record N/A Part of a deployment proposal for - * DNSSEC without a signed DNS root. See the IANA database and Weiler Spec - * for details. Uses the same format as the DS record. - */ - public static final int TA = 32768; - - /** - * DNSSEC Lookaside Validation, RFC 4431. For publishing DNSSEC trust - * anchors outside of the DNS delegation chain. Uses the same format as the - * DS record. RFC 5074 describes a way of using these records. - */ - public static final int DLV = 32769; - private static TypeMnemonic types = new TypeMnemonic(); - - - public static - class TypeMnemonic extends Mnemonic { - private IntMap objects; - - public - TypeMnemonic() { - super("DnsRecordType", CASE_UPPER); - setPrefix("TYPE"); - objects = new IntMap(); - } - - public - void add(int value, String str, DnsRecord proto) { - super.add(value, str); - objects.put(value, proto); - } - - @SuppressWarnings("unchecked") - public - T getProto(int value) { - check(value); - return (T) objects.get(value); - } - - @Override - public - void check(int val) { - DnsRecordType.check(val); - } - } - - static { - // this is so we don't have to make each type constructor public - DnsTypeProtoAssignment.assign(types); - } - - private - DnsRecordType() { - } - - /** - * Checks that a numeric DnsRecordType is valid. - * - * @throws InvalidTypeException The type is out of range. - */ - public static - void check(int val) { - if (val < 0 || val > 0xFFFF) { - throw new InvalidTypeException(val); - } - } - - /** - * Converts a numeric DnsRecordType into a String - * - * @param val The type value. - * - * @return The canonical string representation of the type - * - * @throws InvalidTypeException The type is out of range. - */ - public static - String string(int val) { - return types.getText(val); - } - - /** - * Converts a String representation of an DnsRecordType into its numeric value - * - * @return The type code, or -1 on error. - */ - public static - int value(String s) { - return value(s, false); - } - - /** - * Converts a String representation of an DnsRecordType into its numeric value. - * - * @param s The string representation of the type - * @param numberok Whether a number will be accepted or not. - * - * @return The type code, or -1 on error. - */ - public static - int value(String s, boolean numberok) { - int val = types.getValue(s); - if (val == -1 && numberok) { - val = types.getValue("TYPE" + s); - } - return val; - } - - public static - T getProto(int val) { - return types.getProto(val); - } - - /** - * Is this type valid for a record (a non-meta type)? - */ - public static - boolean isRR(int type) { - switch (type) { - case OPT: - case TKEY: - case TSIG: - case IXFR: - case AXFR: - case MAILB: - case MAILA: - case ANY: - return false; - default: - return true; - } - } - - private static final String ptrSuffix = ".in-addr.arpa"; - - /** - * Guarantees that the specified host name is a FQND. This depends on it's type, which must also be specified. - * - * @param type the resource record type - * @param hostName the hostname - * - * @return the Fully Qualified Domain Name for this hostname, depending on it's type - */ - public static - String ensureFQDN(int type, String hostName) { - // list of RecordTypes from: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/ResourceRecordTypes.html - switch (type) { - case PTR: - if (!hostName.endsWith(ptrSuffix)) { - // PTR absolutely MUST end in '.in-addr.arpa' in order for the DNS server to understand it. - // in this case, hostname is an ip address - return hostName + ptrSuffix; - } - - case A: - case AAAA: - case CAA: - case CNAME: - case MX: - case NAPTR: - case NS: - case SOA: - case SPF: - case SRV: - case TXT: - // resolving a hostname -> ip address, the hostname MUST end in a dot - if (!StringUtil.endsWith(hostName, '.')) { - return hostName + '.'; - } else { - return hostName; - } - - default: - return hostName; - } - } -} diff --git a/src/dorkbox/network/dns/constants/DnsResponseCode.java b/src/dorkbox/network/dns/constants/DnsResponseCode.java deleted file mode 100644 index 22af7740..00000000 --- a/src/dorkbox/network/dns/constants/DnsResponseCode.java +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.constants; - -import dorkbox.network.dns.Mnemonic; - -/** - * Constants and functions relating to DNS rcodes (error values) - * - * @author Brian Wellington - */ - -public final -class DnsResponseCode { - - private static Mnemonic rcodes = new Mnemonic("DNS DnsResponseCode", Mnemonic.CASE_UPPER); - - private static Mnemonic tsigrcodes = new Mnemonic("TSIG rcode", Mnemonic.CASE_UPPER); - - /** - * No error - */ - public static final int NOERROR = 0; - - /** - * Format error - */ - public static final int FORMERR = 1; - - /** - * Server failure - */ - public static final int SERVFAIL = 2; - - /** - * The name does not exist - */ - public static final int NXDOMAIN = 3; - - /** - * The operation requested is not implemented - */ - public static final int NOTIMP = 4; - - /** - * Deprecated synonym for NOTIMP. - */ - public static final int NOTIMPL = 4; - - /** - * The operation was refused by the server - */ - public static final int REFUSED = 5; - - /** - * The name exists - */ - public static final int YXDOMAIN = 6; - - /** - * The RRset (name, type) exists - */ - public static final int YXRRSET = 7; - - /** - * The RRset (name, type) does not exist - */ - public static final int NXRRSET = 8; - - /** - * The requestor is not authorized to perform this operation - */ - public static final int NOTAUTH = 9; - - /** - * The zone specified is not a zone - */ - public static final int NOTZONE = 10; - - - -/* EDNS extended rcodes */ - /** - * Unsupported EDNS level - */ - public static final int BADVERS = 16; - - - -/* TSIG/TKEY only rcodes */ - /** - * The signature is invalid (TSIG/TKEY extended error) - */ - public static final int BADSIG = 16; - - /** - * The key is invalid (TSIG/TKEY extended error) - */ - public static final int BADKEY = 17; - - /** - * The time is out of range (TSIG/TKEY extended error) - */ - public static final int BADTIME = 18; - - /** - * The mode is invalid (TKEY extended error) - */ - public static final int BADMODE = 19; - - /** - * The 'BADNAME' DNS RCODE (20), as defined in RFC2930. - */ - public static final int BADNAME = 20; - - /** - * The 'BADALG' DNS RCODE (21), as defined in RFC2930. - */ - public static final int BADALG = 21; - - static { - rcodes.setMaximum(0xFFF); - rcodes.setPrefix("RESERVED"); - rcodes.setNumericAllowed(true); - - rcodes.add(NOERROR, "NOERROR"); - rcodes.add(FORMERR, "FORMERR"); - rcodes.add(SERVFAIL, "SERVFAIL"); - rcodes.add(NXDOMAIN, "NXDOMAIN"); - rcodes.add(NOTIMP, "NOTIMP"); - rcodes.addAlias(NOTIMP, "NOTIMPL"); - rcodes.add(REFUSED, "REFUSED"); - rcodes.add(YXDOMAIN, "YXDOMAIN"); - rcodes.add(YXRRSET, "YXRRSET"); - rcodes.add(NXRRSET, "NXRRSET"); - rcodes.add(NOTAUTH, "NOTAUTH"); - rcodes.add(NOTZONE, "NOTZONE"); - rcodes.add(BADVERS, "BADVERS"); - - tsigrcodes.setMaximum(0xFFFF); - tsigrcodes.setPrefix("RESERVED"); - tsigrcodes.setNumericAllowed(true); - tsigrcodes.addAll(rcodes); - - tsigrcodes.add(BADSIG, "BADSIG"); - tsigrcodes.add(BADKEY, "BADKEY"); - tsigrcodes.add(BADTIME, "BADTIME"); - tsigrcodes.add(BADMODE, "BADMODE"); - tsigrcodes.add(BADNAME, "BADNAME"); - tsigrcodes.add(BADALG, "BADALG"); - } - - private - DnsResponseCode() {} - - /** - * Converts a numeric DnsResponseCode into a String - */ - public static - String string(int i) { - return rcodes.getText(i); - } - - /** - * Converts a numeric TSIG extended DnsResponseCode into a String - */ - public static - String TSIGstring(int i) { - return tsigrcodes.getText(i); - } - - /** - * Converts a String representation of an DnsResponseCode into its numeric value - */ - public static - int value(String s) { - return rcodes.getValue(s); - } - -} diff --git a/src/dorkbox/network/dns/constants/DnsSection.java b/src/dorkbox/network/dns/constants/DnsSection.java deleted file mode 100644 index 6c52f06c..00000000 --- a/src/dorkbox/network/dns/constants/DnsSection.java +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.constants; - -import dorkbox.network.dns.Mnemonic; - -/** - * Constants and functions relating to DNS message sections - * - * @author Brian Wellington - */ - -public final -class DnsSection { - public static final int TOTAL_SECTION_COUNT = 4; - - /** - * The question (first) section - */ - public static final int QUESTION = 0; - - /** - * The answer (second) section - */ - public static final int ANSWER = 1; - - /** - * The authority (third) section - */ - public static final int AUTHORITY = 2; - - /** - * The additional (fourth) section - */ - public static final int ADDITIONAL = 3; - -/* Aliases for dynamic update */ - /** - * The zone (first) section of a dynamic update message - */ - public static final int ZONE = 0; - - /** - * The prerequisite (second) section of a dynamic update message - */ - public static final int PREREQ = 1; - - /** - * The update (third) section of a dynamic update message - */ - public static final int UPDATE = 2; - - private static Mnemonic sections = new Mnemonic("DnsMessage DnsSection", Mnemonic.CASE_LOWER); - private static String[] longSections = new String[4]; - private static String[] updateSections = new String[4]; - - static { - sections.setMaximum(3); - sections.setNumericAllowed(true); - - sections.add(QUESTION, "qd"); - sections.add(ANSWER, "an"); - sections.add(AUTHORITY, "au"); - sections.add(ADDITIONAL, "ad"); - - longSections[QUESTION] = "QUESTIONS"; - longSections[ANSWER] = "ANSWERS"; - longSections[AUTHORITY] = "AUTHORITY RECORDS"; - longSections[ADDITIONAL] = "ADDITIONAL RECORDS"; - - updateSections[ZONE] = "ZONE"; - updateSections[PREREQ] = "PREREQUISITES"; - updateSections[UPDATE] = "UPDATE RECORDS"; - updateSections[ADDITIONAL] = "ADDITIONAL RECORDS"; - } - - private - DnsSection() {} - - /** - * Converts a numeric DnsSection into an abbreviation String - */ - public static - String string(int i) { - return sections.getText(i); - } - - /** - * Converts a numeric DnsSection into a full description String - */ - public static - String longString(int i) { - sections.check(i); - return longSections[i]; - } - - /** - * Converts a numeric DnsSection into a full description String for an update - * DnsMessage. - */ - public static - String updString(int i) { - sections.check(i); - return updateSections[i]; - } - - /** - * Converts a String representation of a DnsSection into its numeric value - */ - public static - int value(String s) { - return sections.getValue(s); - } - -} diff --git a/src/dorkbox/network/dns/constants/ExtendedFlags.java b/src/dorkbox/network/dns/constants/ExtendedFlags.java deleted file mode 100644 index f5ad500d..00000000 --- a/src/dorkbox/network/dns/constants/ExtendedFlags.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.constants; - -import dorkbox.network.dns.Mnemonic; - -/** - * Constants and functions relating to EDNS flags. - * - * @author Brian Wellington - */ - -public -enum ExtendedFlags { - - - /** - * dnssec ok - */ - DO(0x8000, "do"); - - private static Mnemonic extflags = new Mnemonic("EDNS Flag", Mnemonic.CASE_LOWER); - static { - extflags.setMaximum(0xFFFF); - extflags.setPrefix("FLAG"); - extflags.setNumericAllowed(true); - - extflags.add(DO.flagValue, "do"); - } - - - private final byte flagValue; - private final String textValue; - - ExtendedFlags(final int flagValue, final String textValue) { - this.flagValue = (byte) flagValue; - this.textValue = textValue; - } - - public - byte value() { - return flagValue; - } - - public - String string() { - return textValue; - } - - /** - * Converts a numeric extended flag into a String - */ - public static - String string(int i) { - return extflags.getText(i); - } - - /** - * Converts a textual representation of an extended flag into its numeric - * value - */ - public static - int value(String s) { - return extflags.getValue(s); - } - -} diff --git a/src/dorkbox/network/dns/constants/Flags.java b/src/dorkbox/network/dns/constants/Flags.java deleted file mode 100644 index e3ab0980..00000000 --- a/src/dorkbox/network/dns/constants/Flags.java +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.constants; - -import dorkbox.network.dns.Mnemonic; - -/** - * Constants and functions relating to flags in the DNS header. - * - * In DNS query header there is a flag field in the second 16 bit word in query from bit 5 through bit 11 ([RFC1035] section 4.1.1) - * - * https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-12 - */ - -public -enum Flags { - - /** - * query/response - */ - QR(0, "qr"), - - /** - * authoritative answer - */ - AA(5, "aa"), - - /** - * truncated - */ - TC(6, "tc"), - - /** - * recursion desired - */ - RD(7, "rd"), - - /** - * recursion available - */ - RA(8, "ra"), - - /** - * RESERVED - */ - RESERVED(9, "__"), - - /** - * authenticated data - */ - AD(10, "ad"), - - /** - * (security) checking disabled - */ - CD(11, "cd"), - - /** - * dnssec ok (extended) - */ - DO(ExtendedFlags.DO.value(), ExtendedFlags.DO.string()); - - - private static Mnemonic flags = new Mnemonic("DNS Header Flag", Mnemonic.CASE_LOWER); - static { - flags.setMaximum(0xF); - flags.setPrefix("FLAG"); - flags.setNumericAllowed(true); - - flags.add(QR.flagValue, "qr"); - flags.add(AA.flagValue, "aa"); - flags.add(TC.flagValue, "tc"); - flags.add(RD.flagValue, "rd"); - flags.add(RA.flagValue, "ra"); - flags.add(AD.flagValue, "ad"); - flags.add(CD.flagValue, "cd"); - } - - private final byte flagValue; - private final String textValue; - - Flags(final int flagValue, final String textValue) { - this.flagValue = (byte) flagValue; - this.textValue = textValue; - } - - public - byte value() { - return flagValue; - } - - public - String string() { - return textValue; - } - - - public static - Flags toFlag(final int flagBit) { - for (Flags flag : values()) { - if (flag.value() == flagBit) { - return flag; - } - } - - throw new IllegalArgumentException("Invalid flag " + flagBit); - } - - public static - Flags toFlag(final String flagName) { - for (Flags flag : values()) { - if (flag.string().equals(flagName)) { - return flag; - } - } - - throw new IllegalArgumentException("Invalid flag " + flagName); - } - - - // /** - // * Converts a numeric Flag into a String - // */ - // public static - // String string(int i) { - // return flags.getText(i); - // } - // - // /** - // * Converts a String representation of an Flag into its numeric value - // */ - // public static - // int value(String s) { - // return flags.getValue(s); - // } - - /** - * Indicates if a bit in the flags field is a flag or not. If it's part of the rcode or opcode, it's not. - */ - public static - boolean isFlag(int index) { - // Checks that a numeric value is within the range - if (index < 0 || index > 0xF || (index >= 1 && index <= 4) || (index >= 12)) { - return false; - } - - return true; - } -} diff --git a/src/dorkbox/network/dns/exceptions/InvalidDClassException.java b/src/dorkbox/network/dns/exceptions/InvalidDClassException.java deleted file mode 100644 index e115670b..00000000 --- a/src/dorkbox/network/dns/exceptions/InvalidDClassException.java +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.exceptions; - -/** - * An exception thrown when an invalid dclass code is specified. - * - * @author Brian Wellington - */ - -public -class InvalidDClassException extends IllegalArgumentException { - - public - InvalidDClassException(int dclass) { - super("Invalid DNS class: " + dclass); - } - -} diff --git a/src/dorkbox/network/dns/exceptions/InvalidTTLException.java b/src/dorkbox/network/dns/exceptions/InvalidTTLException.java deleted file mode 100644 index c1deb810..00000000 --- a/src/dorkbox/network/dns/exceptions/InvalidTTLException.java +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.exceptions; - -/** - * An exception thrown when an invalid TTL is specified. - * - * @author Brian Wellington - */ - -public -class InvalidTTLException extends IllegalArgumentException { - - public - InvalidTTLException(long ttl) { - super("Invalid DNS TTL: " + ttl); - } - -} diff --git a/src/dorkbox/network/dns/exceptions/InvalidTypeException.java b/src/dorkbox/network/dns/exceptions/InvalidTypeException.java deleted file mode 100644 index eae90e74..00000000 --- a/src/dorkbox/network/dns/exceptions/InvalidTypeException.java +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.exceptions; - -/** - * An exception thrown when an invalid type code is specified. - * - * @author Brian Wellington - */ - -public -class InvalidTypeException extends IllegalArgumentException { - - public - InvalidTypeException(int type) { - super("Invalid DNS type: " + type); - } - -} diff --git a/src/dorkbox/network/dns/exceptions/NameTooLongException.java b/src/dorkbox/network/dns/exceptions/NameTooLongException.java deleted file mode 100644 index 2841098f..00000000 --- a/src/dorkbox/network/dns/exceptions/NameTooLongException.java +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2002-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.exceptions; - -/** - * An exception thrown when a name is longer than the maximum length of a DNS - * name. - * - * @author Brian Wellington - */ - -public -class NameTooLongException extends WireParseException { - - public - NameTooLongException() { - super(); - } - - public - NameTooLongException(String s) { - super(s); - } - -} diff --git a/src/dorkbox/network/dns/exceptions/RelativeNameException.java b/src/dorkbox/network/dns/exceptions/RelativeNameException.java deleted file mode 100644 index 3f729aaf..00000000 --- a/src/dorkbox/network/dns/exceptions/RelativeNameException.java +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.exceptions; - -import dorkbox.network.dns.Name; - -/** - * An exception thrown when a relative name is passed as an argument to - * a method requiring an absolute name. - * - * @author Brian Wellington - */ - -public -class RelativeNameException extends IllegalArgumentException { - - public - RelativeNameException(Name name) { - super("'" + name + "' is not an absolute name"); - } - - public - RelativeNameException(String s) { - super(s); - } - -} diff --git a/src/dorkbox/network/dns/exceptions/TextParseException.java b/src/dorkbox/network/dns/exceptions/TextParseException.java deleted file mode 100644 index 186fb37f..00000000 --- a/src/dorkbox/network/dns/exceptions/TextParseException.java +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2002-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.exceptions; - -import java.io.IOException; - -/** - * An exception thrown when unable to parse text. - * - * @author Brian Wellington - */ - -public -class TextParseException extends IOException { - - public - TextParseException() { - super(); - } - - public - TextParseException(String s) { - super(s); - } - -} diff --git a/src/dorkbox/network/dns/exceptions/WireParseException.java b/src/dorkbox/network/dns/exceptions/WireParseException.java deleted file mode 100644 index f8ea4ce9..00000000 --- a/src/dorkbox/network/dns/exceptions/WireParseException.java +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.exceptions; - -import java.io.IOException; - -/** - * An exception thrown when a DNS message is invalid. - * - * @author Brian Wellington - */ - -public -class WireParseException extends IOException { - - public - WireParseException() { - super(); - } - - public - WireParseException(String s) { - super(s); - } - - public - WireParseException(String s, Throwable cause) { - super(s); - initCause(cause); - } - -} diff --git a/src/dorkbox/network/dns/exceptions/ZoneTransferException.java b/src/dorkbox/network/dns/exceptions/ZoneTransferException.java deleted file mode 100644 index 37e47325..00000000 --- a/src/dorkbox/network/dns/exceptions/ZoneTransferException.java +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.exceptions; - -/** - * An exception thrown when a zone transfer fails. - * - * @author Brian Wellington - */ - -public -class ZoneTransferException extends Exception { - - public - ZoneTransferException() { - super(); - } - - public - ZoneTransferException(String s) { - super(s); - } - -} diff --git a/src/dorkbox/network/dns/records/A6Record.java b/src/dorkbox/network/dns/records/A6Record.java deleted file mode 100644 index 214bac7d..00000000 --- a/src/dorkbox/network/dns/records/A6Record.java +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Address; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * A6 Record - maps a domain name to an IPv6 address (experimental) - * - * @author Brian Wellington - */ - -public -class A6Record extends DnsRecord { - - private static final long serialVersionUID = -8815026887337346789L; - - private int prefixBits; - private InetAddress suffix; - private Name prefix; - - A6Record() {} - - @Override - DnsRecord getObject() { - return new A6Record(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - prefixBits = in.readU8(); - int suffixbits = 128 - prefixBits; - int suffixbytes = (suffixbits + 7) / 8; - if (prefixBits < 128) { - byte[] bytes = new byte[16]; - in.readByteArray(bytes, 16 - suffixbytes, suffixbytes); - suffix = InetAddress.getByAddress(bytes); - } - if (prefixBits > 0) { - prefix = new Name(in); - } - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU8(prefixBits); - if (suffix != null) { - int suffixbits = 128 - prefixBits; - int suffixbytes = (suffixbits + 7) / 8; - byte[] data = suffix.getAddress(); - out.writeByteArray(data, 16 - suffixbytes, suffixbytes); - } - if (prefix != null) { - prefix.toWire(out, null, canonical); - } - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(prefixBits); - if (suffix != null) { - sb.append(" "); - sb.append(suffix.getHostAddress()); - } - if (prefix != null) { - sb.append(" "); - sb.append(prefix); - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - prefixBits = st.getUInt8(); - if (prefixBits > 128) { - throw st.exception("prefix bits must be [0..128]"); - } - else if (prefixBits < 128) { - String s = st.getString(); - try { - suffix = Address.getByAddress(s, Address.IPv6); - } catch (UnknownHostException e) { - throw st.exception("invalid IPv6 address: " + s); - } - } - if (prefixBits > 0) { - prefix = st.getName(origin); - } - } - - /** - * Creates an A6 Record from the given data - * - * @param prefixBits The number of bits in the address prefix - * @param suffix The address suffix - * @param prefix The name of the prefix - */ - public - A6Record(Name name, int dclass, long ttl, int prefixBits, InetAddress suffix, Name prefix) { - super(name, DnsRecordType.A6, dclass, ttl); - this.prefixBits = checkU8("prefixBits", prefixBits); - if (suffix != null && Address.familyOf(suffix) != Address.IPv6) { - throw new IllegalArgumentException("invalid IPv6 address"); - } - this.suffix = suffix; - if (prefix != null) { - this.prefix = checkName("prefix", prefix); - } - } - - /** - * Returns the number of bits in the prefix - */ - public - int getPrefixBits() { - return prefixBits; - } - - /** - * Returns the address suffix - */ - public - InetAddress getSuffix() { - return suffix; - } - - /** - * Returns the address prefix - */ - public - Name getPrefix() { - return prefix; - } - -} diff --git a/src/dorkbox/network/dns/records/AAAARecord.java b/src/dorkbox/network/dns/records/AAAARecord.java deleted file mode 100644 index 65a4515c..00000000 --- a/src/dorkbox/network/dns/records/AAAARecord.java +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Address; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * IPv6 Address Record - maps a domain name to an IPv6 address - * - * @author Brian Wellington - */ - -public -class AAAARecord extends DnsRecord { - - private static final long serialVersionUID = -4588601512069748050L; - - private byte[] address; - - AAAARecord() {} - - @Override - DnsRecord getObject() { - return new AAAARecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - address = in.readByteArray(16); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeByteArray(address); - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - InetAddress addr; - try { - addr = InetAddress.getByAddress(null, address); - } catch (UnknownHostException e) { - return; - } - if (addr.getAddress().length == 4) { - // Deal with Java's broken handling of mapped IPv4 addresses. - sb.append("0:0:0:0:0:ffff:"); - int high = ((address[12] & 0xFF) << 8) + (address[13] & 0xFF); - int low = ((address[14] & 0xFF) << 8) + (address[15] & 0xFF); - sb.append(Integer.toHexString(high)); - sb.append(':'); - sb.append(Integer.toHexString(low)); - - return; - } - - sb.append(addr.getHostAddress()); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - address = st.getAddressBytes(Address.IPv6); - } - - /** - * Creates an AAAA Record from the given data - * - * @param address The address that the name refers - */ - public - AAAARecord(Name name, int dclass, long ttl, InetAddress address) { - super(name, DnsRecordType.AAAA, dclass, ttl); - if (Address.familyOf(address) != Address.IPv6) { - throw new IllegalArgumentException("invalid IPv6 address"); - } - this.address = address.getAddress(); - } - - /** - * Creates an AAAA Record from the given data - * - * @param address The address that the name refers to as a byte array. This value is NOT COPIED. - */ - public - AAAARecord(Name name, int dclass, long ttl, byte[] address) { - super(name, DnsRecordType.AAAA, dclass, ttl); - if (address.length != Address.addressLength(Address.IPv6)) { - throw new IllegalArgumentException("invalid IPv6 address"); - } - this.address = address; - } - - /** - * Returns the address - */ - public - InetAddress getAddress() { - try { - if (name == null) { - return InetAddress.getByAddress(address); - } - else { - return InetAddress.getByAddress(name.toString(true), address); - } - } catch (UnknownHostException e) { - return null; - } - } -} diff --git a/src/dorkbox/network/dns/records/AFSDBRecord.java b/src/dorkbox/network/dns/records/AFSDBRecord.java deleted file mode 100644 index 900852df..00000000 --- a/src/dorkbox/network/dns/records/AFSDBRecord.java +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * AFS Data Base Record - maps a domain name to the name of an AFS cell - * database server. - * - * @author Brian Wellington - */ - -public -class AFSDBRecord extends U16NameBase { - - private static final long serialVersionUID = 3034379930729102437L; - - AFSDBRecord() {} - - @Override - DnsRecord getObject() { - return new AFSDBRecord(); - } - - /** - * Creates an AFSDB Record from the given data. - * - * @param subtype Indicates the type of service provided by the host. - * @param host The host providing the service. - */ - public - AFSDBRecord(Name name, int dclass, long ttl, int subtype, Name host) { - super(name, DnsRecordType.AFSDB, dclass, ttl, subtype, "subtype", host, "host"); - } - - /** - * Gets the subtype indicating the service provided by the host. - */ - public - int getSubtype() { - return getU16Field(); - } - - /** - * Gets the host providing service for the domain. - */ - public - Name getHost() { - return getNameField(); - } -} diff --git a/src/dorkbox/network/dns/records/APLRecord.java b/src/dorkbox/network/dns/records/APLRecord.java deleted file mode 100644 index 920436b8..00000000 --- a/src/dorkbox/network/dns/records/APLRecord.java +++ /dev/null @@ -1,305 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.network.dns.utils.Address; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.network.dns.utils.base16; - -/** - * APL - Address Prefix List. See RFC 3123. - * - * @author Brian Wellington - */ - -/* - * Note: this currently uses the same constants as the Address class; - * this could change if more constants are defined for APL records. - */ - -public -class APLRecord extends DnsRecord { - - private static final long serialVersionUID = -1348173791712935864L; - private List elements; - - - public static - class Element { - public final int family; - public final boolean negative; - public final int prefixLength; - public final Object address; - - /** - * Creates an APL element corresponding to an IPv4 or IPv6 prefix. - * - * @param negative Indicates if this prefix is a negation. - * @param address The IPv4 or IPv6 address. - * @param prefixLength The length of this prefix, in bits. - * - * @throws IllegalArgumentException The prefix length is invalid. - */ - public - Element(boolean negative, InetAddress address, int prefixLength) { - this(Address.familyOf(address), negative, address, prefixLength); - } - - private - Element(int family, boolean negative, Object address, int prefixLength) { - this.family = family; - this.negative = negative; - this.address = address; - this.prefixLength = prefixLength; - if (!validatePrefixLength(family, prefixLength)) { - throw new IllegalArgumentException("invalid prefix " + "length"); - } - } - - public - int hashCode() { - return address.hashCode() + prefixLength + (negative ? 1 : 0); - } - - public - boolean equals(Object arg) { - if (arg == null || !(arg instanceof Element)) { - return false; - } - Element elt = (Element) arg; - return (family == elt.family && negative == elt.negative && prefixLength == elt.prefixLength && address.equals(elt.address)); - } - - public - String toString() { - StringBuilder sb = new StringBuilder(); - if (negative) { - sb.append("!"); - } - sb.append(family); - sb.append(":"); - if (family == Address.IPv4 || family == Address.IPv6) { - sb.append(((InetAddress) address).getHostAddress()); - } - else { - sb.append(base16.toString((byte[]) address)); - } - sb.append("/"); - sb.append(prefixLength); - return sb.toString(); - } - } - - APLRecord() {} - - @Override - DnsRecord getObject() { - return new APLRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - elements = new ArrayList(1); - while (in.remaining() != 0) { - int family = in.readU16(); - int prefix = in.readU8(); - int length = in.readU8(); - boolean negative = (length & 0x80) != 0; - length &= ~0x80; - - byte[] data = in.readByteArray(length); - Element element; - if (!validatePrefixLength(family, prefix)) { - throw new WireParseException("invalid prefix length"); - } - - if (family == Address.IPv4 || family == Address.IPv6) { - data = parseAddress(data, Address.addressLength(family)); - InetAddress addr = InetAddress.getByAddress(data); - element = new Element(negative, addr, prefix); - } - else { - element = new Element(family, negative, data, prefix); - } - elements.add(element); - - } - } - - private static - boolean validatePrefixLength(int family, int prefixLength) { - if (prefixLength < 0 || prefixLength >= 256) { - return false; - } - if ((family == Address.IPv4 && prefixLength > 32) || (family == Address.IPv6 && prefixLength > 128)) { - return false; - } - return true; - } - - private static - byte[] parseAddress(byte[] in, int length) throws WireParseException { - if (in.length > length) { - throw new WireParseException("invalid address length"); - } - if (in.length == length) { - return in; - } - byte[] out = new byte[length]; - System.arraycopy(in, 0, out, 0, in.length); - return out; - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - for (Iterator it = elements.iterator(); it.hasNext(); ) { - Element element = (Element) it.next(); - int length = 0; - byte[] data; - if (element.family == Address.IPv4 || element.family == Address.IPv6) { - InetAddress addr = (InetAddress) element.address; - data = addr.getAddress(); - length = addressLength(data); - } - else { - data = (byte[]) element.address; - length = data.length; - } - int wlength = length; - if (element.negative) { - wlength |= 0x80; - } - out.writeU16(element.family); - out.writeU8(element.prefixLength); - out.writeU8(wlength); - out.writeByteArray(data, 0, length); - } - } - - @Override - void rrToString(StringBuilder sb) { - for (Iterator it = elements.iterator(); it.hasNext(); ) { - Element element = (Element) it.next(); - sb.append(element); - if (it.hasNext()) { - sb.append(" "); - } - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - elements = new ArrayList(1); - while (true) { - Tokenizer.Token t = st.get(); - if (!t.isString()) { - break; - } - - boolean negative = false; - int family = 0; - int prefix = 0; - - String s = t.value; - int start = 0; - if (s.startsWith("!")) { - negative = true; - start = 1; - } - int colon = s.indexOf(':', start); - if (colon < 0) { - throw st.exception("invalid address prefix element"); - } - int slash = s.indexOf('/', colon); - if (slash < 0) { - throw st.exception("invalid address prefix element"); - } - - String familyString = s.substring(start, colon); - String addressString = s.substring(colon + 1, slash); - String prefixString = s.substring(slash + 1); - - try { - family = Integer.parseInt(familyString); - } catch (NumberFormatException e) { - throw st.exception("invalid family"); - } - if (family != Address.IPv4 && family != Address.IPv6) { - throw st.exception("unknown family"); - } - - try { - prefix = Integer.parseInt(prefixString); - } catch (NumberFormatException e) { - throw st.exception("invalid prefix length"); - } - - if (!validatePrefixLength(family, prefix)) { - throw st.exception("invalid prefix length"); - } - - byte[] bytes = Address.toByteArray(addressString, family); - if (bytes == null) { - throw st.exception("invalid IP address " + addressString); - } - - InetAddress address = InetAddress.getByAddress(bytes); - elements.add(new Element(negative, address, prefix)); - } - st.unget(); - } - - private static - int addressLength(byte[] addr) { - for (int i = addr.length - 1; i >= 0; i--) { - if (addr[i] != 0) { - return i + 1; - } - } - return 0; - } - - /** - * Creates an APL Record from the given data. - * - * @param elements The list of APL elements. - */ - public - APLRecord(Name name, int dclass, long ttl, List elements) { - super(name, DnsRecordType.APL, dclass, ttl); - this.elements = new ArrayList(elements.size()); - for (Iterator it = elements.iterator(); it.hasNext(); ) { - Object o = it.next(); - if (!(o instanceof Element)) { - throw new IllegalArgumentException("illegal element"); - } - Element element = (Element) o; - if (element.family != Address.IPv4 && element.family != Address.IPv6) { - throw new IllegalArgumentException("unknown family"); - } - this.elements.add(element); - - } - } - - /** - * Returns the list of APL elements. - */ - public - List getElements() { - return elements; - } - -} diff --git a/src/dorkbox/network/dns/records/ARecord.java b/src/dorkbox/network/dns/records/ARecord.java deleted file mode 100644 index 4278e314..00000000 --- a/src/dorkbox/network/dns/records/ARecord.java +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Address; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Address Record - maps a domain name to an Internet address - * - * @author Brian Wellington - */ - -public -class ARecord extends DnsRecord { - - private static final long serialVersionUID = -2172609200849142323L; - - private int addr; - - ARecord() {} - - @Override - DnsRecord getObject() { - return new ARecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - addr = fromArray(in.readByteArray(4)); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU32(((long) addr) & 0xFFFFFFFFL); - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(Address.toDottedQuad(toArray(addr))); - } - - private static - byte[] toArray(int addr) { - byte[] bytes = new byte[4]; - bytes[0] = (byte) ((addr >>> 24) & 0xFF); - bytes[1] = (byte) ((addr >>> 16) & 0xFF); - bytes[2] = (byte) ((addr >>> 8) & 0xFF); - bytes[3] = (byte) (addr & 0xFF); - return bytes; - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - addr = fromArray(st.getAddressBytes(Address.IPv4)); - } - - private static - int fromArray(byte[] array) { - return (((array[0] & 0xFF) << 24) | ((array[1] & 0xFF) << 16) | ((array[2] & 0xFF) << 8) | (array[3] & 0xFF)); - } - - /** - * Creates an A Record from the given data - * - * @param address The address that the name refers to - */ - public - ARecord(Name name, int dclass, long ttl, InetAddress address) { - super(name, DnsRecordType.A, dclass, ttl); - if (Address.familyOf(address) != Address.IPv4) { - throw new IllegalArgumentException("invalid IPv4 address"); - } - addr = fromArray(address.getAddress()); - } - - /** - * Creates an A Record from the given data - * - * @param address The address that the name refers to as a byte array. This value is NOT COPIED. - */ - public - ARecord(Name name, int dclass, long ttl, byte[] address) { - super(name, DnsRecordType.A, dclass, ttl); - if (address.length != Address.addressLength(Address.IPv4)) { - throw new IllegalArgumentException("invalid IPv4 address"); - } - addr = fromArray(address); - } - - /** - * Returns the Internet address - */ - public - InetAddress getAddress() { - try { - if (name == null) { - return InetAddress.getByAddress(toArray(addr)); - } - else { - return InetAddress.getByAddress(name.toString(true), toArray(addr)); - } - } catch (UnknownHostException e) { - return null; - } - } -} diff --git a/src/dorkbox/network/dns/records/CAARecord.java b/src/dorkbox/network/dns/records/CAARecord.java deleted file mode 100644 index 864713f8..00000000 --- a/src/dorkbox/network/dns/records/CAARecord.java +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Certification Authority Authorization - * - * @author Brian Wellington - */ - -public -class CAARecord extends DnsRecord { - - private static final long serialVersionUID = 8544304287274216443L; - private int flags; - private byte[] tag; - private byte[] value; - - - public static - class Flags { - public static final int IssuerCritical = 128; - - private - Flags() {} - } - - CAARecord() {} - - @Override - DnsRecord getObject() { - return new CAARecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - flags = in.readU8(); - tag = in.readCountedString(); - value = in.readByteArray(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU8(flags); - out.writeCountedString(tag); - out.writeByteArray(value); - } - - @Override - void rrToString(StringBuilder sb) { - sb.append(flags); - sb.append(" "); - sb.append(byteArrayToString(tag, false)); - sb.append(" "); - sb.append(byteArrayToString(value, true)); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - flags = st.getUInt8(); - try { - tag = byteArrayFromString(st.getString()); - value = byteArrayFromString(st.getString()); - } catch (TextParseException e) { - throw st.exception(e.getMessage()); - } - } - - /** - * Creates an CAA Record from the given data. - * - * @param flags The flags. - * @param tag The tag. - * @param value The value. - */ - public - CAARecord(Name name, int dclass, long ttl, int flags, String tag, String value) { - super(name, DnsRecordType.CAA, dclass, ttl); - this.flags = checkU8("flags", flags); - try { - this.tag = byteArrayFromString(tag); - this.value = byteArrayFromString(value); - } catch (TextParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } - } - - /** - * Returns the flags. - */ - public - int getFlags() { - return flags; - } - - /** - * Returns the tag. - */ - public - String getTag() { - return byteArrayToString(tag, false); - } - - /** - * Returns the value - */ - public - String getValue() { - return byteArrayToString(value, false); - } - -} diff --git a/src/dorkbox/network/dns/records/CERTRecord.java b/src/dorkbox/network/dns/records/CERTRecord.java deleted file mode 100644 index 531f3cb9..00000000 --- a/src/dorkbox/network/dns/records/CERTRecord.java +++ /dev/null @@ -1,257 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Mnemonic; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Options; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.util.Base64Fast; -import dorkbox.util.OS; - -/** - * Certificate Record - Stores a certificate associated with a name. The - * certificate might also be associated with a KEYRecord. - * - * @author Brian Wellington - * @see KEYRecord - */ - -public -class CERTRecord extends DnsRecord { - - /** - * PKIX (X.509v3) - */ - public static final int PKIX = CertificateType.PKIX; - /** - * Simple Public Key Infrastructure - */ - public static final int SPKI = CertificateType.SPKI; - /** - * Pretty Good Privacy - */ - public static final int PGP = CertificateType.PGP; - /** - * Certificate format defined by URI - */ - public static final int URI = CertificateType.URI; - /** - * Certificate format defined by IOD - */ - public static final int OID = CertificateType.OID; - private static final long serialVersionUID = 4763014646517016835L; - private int certType, keyTag; - private int alg; - private byte[] cert; - - - public static - class CertificateType { - /** - * PKIX (X.509v3) - */ - public static final int PKIX = 1; - /** - * Simple Public Key Infrastructure - */ - public static final int SPKI = 2; - /** - * Pretty Good Privacy - */ - public static final int PGP = 3; - /** - * URL of an X.509 data object - */ - public static final int IPKIX = 4; - /** - * URL of an SPKI certificate - */ - public static final int ISPKI = 5; - /** - * Fingerprint and URL of an OpenPGP packet - */ - public static final int IPGP = 6; - /** - * Attribute Certificate - */ - public static final int ACPKIX = 7; - /** - * URL of an Attribute Certificate - */ - public static final int IACPKIX = 8; - /** - * Certificate format defined by URI - */ - public static final int URI = 253; - /** - * Certificate format defined by OID - */ - public static final int OID = 254; - private static Mnemonic types = new Mnemonic("Certificate type", Mnemonic.CASE_UPPER); - - /** - * Certificate type identifiers. See RFC 4398 for more detail. - */ - - private - CertificateType() {} - - static { - types.setMaximum(0xFFFF); - types.setNumericAllowed(true); - - types.add(PKIX, "PKIX"); - types.add(SPKI, "SPKI"); - types.add(PGP, "PGP"); - types.add(PKIX, "IPKIX"); - types.add(SPKI, "ISPKI"); - types.add(PGP, "IPGP"); - types.add(PGP, "ACPKIX"); - types.add(PGP, "IACPKIX"); - types.add(URI, "URI"); - types.add(OID, "OID"); - } - - /** - * Converts a certificate type into its textual representation - */ - public static - String string(int type) { - return types.getText(type); - } - - /** - * Converts a textual representation of an certificate type into its - * numeric code. Integers in the range 0..65535 are also accepted. - * - * @param s The textual representation of the algorithm - * - * @return The algorithm code, or -1 on error. - */ - public static - int value(String s) { - return types.getValue(s); - } - } - - CERTRecord() {} - - @Override - DnsRecord getObject() { - return new CERTRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - certType = in.readU16(); - keyTag = in.readU16(); - alg = in.readU8(); - cert = in.readByteArray(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU16(certType); - out.writeU16(keyTag); - out.writeU8(alg); - out.writeByteArray(cert); - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(certType); - sb.append(" "); - sb.append(keyTag); - sb.append(" "); - sb.append(alg); - - if (cert != null) { - if (Options.check("multiline")) { - sb.append(" ("); - sb.append(OS.LINE_SEPARATOR); - - sb.append(Base64Fast.formatString(Base64Fast.encode2(cert), 64, "\t", true)); - } - else { - sb.append(" "); - sb.append(Base64Fast.encode2(cert)); - } - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - String certTypeString = st.getString(); - certType = CertificateType.value(certTypeString); - if (certType < 0) { - throw st.exception("Invalid certificate type: " + certTypeString); - } - keyTag = st.getUInt16(); - String algString = st.getString(); - alg = DNSSEC.Algorithm.value(algString); - if (alg < 0) { - throw st.exception("Invalid algorithm: " + algString); - } - cert = st.getBase64(); - } - - /** - * Creates a CERT Record from the given data - * - * @param certType The type of certificate (see constants) - * @param keyTag The ID of the associated KEYRecord, if present - * @param alg The algorithm of the associated KEYRecord, if present - * @param cert Binary data representing the certificate - */ - public - CERTRecord(Name name, int dclass, long ttl, int certType, int keyTag, int alg, byte[] cert) { - super(name, DnsRecordType.CERT, dclass, ttl); - this.certType = checkU16("certType", certType); - this.keyTag = checkU16("keyTag", keyTag); - this.alg = checkU8("alg", alg); - this.cert = cert; - } - - /** - * Returns the type of certificate - */ - public - int getCertType() { - return certType; - } - - /** - * Returns the ID of the associated KEYRecord, if present - */ - public - int getKeyTag() { - return keyTag; - } - - /** - * Returns the algorithm of the associated KEYRecord, if present - */ - public - int getAlgorithm() { - return alg; - } - - /** - * Returns the binary representation of the certificate - */ - public - byte[] getCert() { - return cert; - } - -} diff --git a/src/dorkbox/network/dns/records/CNAMERecord.java b/src/dorkbox/network/dns/records/CNAMERecord.java deleted file mode 100644 index 2844ac76..00000000 --- a/src/dorkbox/network/dns/records/CNAMERecord.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * CNAME Record - maps an alias to its real name - * - * @author Brian Wellington - */ - -public -class CNAMERecord extends SingleCompressedNameBase { - - private static final long serialVersionUID = -4020373886892538580L; - - CNAMERecord() {} - - @Override - DnsRecord getObject() { - return new CNAMERecord(); - } - - /** - * Creates a new CNAMERecord with the given data - * - * @param alias The name to which the CNAME alias points - */ - public - CNAMERecord(Name name, int dclass, long ttl, Name alias) { - super(name, DnsRecordType.CNAME, dclass, ttl, alias, "alias"); - } - - /** - * Gets the target of the CNAME Record - */ - public - Name getTarget() { - return getSingleName(); - } - - /** - * Gets the alias specified by the CNAME Record - */ - public - Name getAlias() { - return getSingleName(); - } - -} diff --git a/src/dorkbox/network/dns/records/ClientSubnetOption.java b/src/dorkbox/network/dns/records/ClientSubnetOption.java deleted file mode 100644 index e37f60de..00000000 --- a/src/dorkbox/network/dns/records/ClientSubnetOption.java +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.network.dns.utils.Address; - -/** - * The Client Subnet EDNS Option, defined in - * http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-00 - * ("Client subnet in DNS requests"). - *

- * The option is used to convey information about the IP address of the - * originating client, so that an authoritative server can make decisions - * based on this address, rather than the address of the intermediate - * caching name server. - *

- * The option is transmitted as part of an OPTRecord in the additional section - * of a DNS message, as defined by RFC 2671 (EDNS0). - *

- * The wire format of the option contains a 2-byte length field (1 for IPv4, 2 - * for IPv6), a 1-byte source netmask, a 1-byte scope netmask, and an address - * truncated to the source netmask length (where the final octet is padded with - * bits set to 0) - * - * @author Brian Wellington - * @author Ming Zhou <mizhou@bnivideo.com>, Beaumaris Networks - * @see OPTRecord - */ -public -class ClientSubnetOption extends EDNSOption { - - private static final long serialVersionUID = -3868158449890266347L; - - private int family; - private int sourceNetmask; - private int scopeNetmask; - private InetAddress address; - - ClientSubnetOption() { - super(EDNSOption.Code.CLIENT_SUBNET); - } - - /** - * Construct a Client Subnet option with scope netmask set to 0. - * - * @param sourceNetmask The length of the netmask pertaining to the query. - * In replies, it mirrors the same value as in the requests. - * @param address The address of the client. - * - * @see ClientSubnetOption - */ - public - ClientSubnetOption(int sourceNetmask, InetAddress address) { - this(sourceNetmask, 0, address); - } - - /** - * Construct a Client Subnet option. Note that the number of significant bits - * in the address must not be greater than the supplied source netmask. There - * may also be issues related to Java's handling of mapped addresses - * - * @param sourceNetmask The length of the netmask pertaining to the query. - * In replies, it mirrors the same value as in the requests. - * @param scopeNetmask The length of the netmask pertaining to the reply. - * In requests, it MUST be set to 0. In responses, this may or may not match - * the source netmask. - * @param address The address of the client. - */ - public - ClientSubnetOption(int sourceNetmask, int scopeNetmask, InetAddress address) { - super(EDNSOption.Code.CLIENT_SUBNET); - - this.family = Address.familyOf(address); - this.sourceNetmask = checkMaskLength("source netmask", this.family, sourceNetmask); - this.scopeNetmask = checkMaskLength("scope netmask", this.family, scopeNetmask); - this.address = Address.truncate(address, sourceNetmask); - - if (!address.equals(this.address)) { - throw new IllegalArgumentException("source netmask is not " + "valid for address"); - } - } - - private static - int checkMaskLength(String field, int family, int val) { - int max = Address.addressLength(family) * 8; - if (val < 0 || val > max) { - throw new IllegalArgumentException("\"" + field + "\" " + val + " must be in the range " + "[0.." + max + "]"); - } - return val; - } - - /** - * Returns the family of the network address. This will be either IPv4 (1) - * or IPv6 (2). - */ - public - int getFamily() { - return family; - } - - /** - * Returns the source netmask. - */ - public - int getSourceNetmask() { - return sourceNetmask; - } - - /** - * Returns the scope netmask. - */ - public - int getScopeNetmask() { - return scopeNetmask; - } - - /** - * Returns the IP address of the client. - */ - public - InetAddress getAddress() { - return address; - } - - @Override - void optionFromWire(DnsInput in) throws WireParseException { - family = in.readU16(); - if (family != Address.IPv4 && family != Address.IPv6) { - throw new WireParseException("unknown address family"); - } - sourceNetmask = in.readU8(); - if (sourceNetmask > Address.addressLength(family) * 8) { - throw new WireParseException("invalid source netmask"); - } - scopeNetmask = in.readU8(); - if (scopeNetmask > Address.addressLength(family) * 8) { - throw new WireParseException("invalid scope netmask"); - } - - // Read the truncated address - byte[] addr = in.readByteArray(); - if (addr.length != (sourceNetmask + 7) / 8) { - throw new WireParseException("invalid address"); - } - - // Convert it to a full length address. - byte[] fulladdr = new byte[Address.addressLength(family)]; - System.arraycopy(addr, 0, fulladdr, 0, addr.length); - - try { - address = InetAddress.getByAddress(fulladdr); - } catch (UnknownHostException e) { - throw new WireParseException("invalid address", e); - } - - InetAddress tmp = Address.truncate(address, sourceNetmask); - if (!tmp.equals(address)) { - throw new WireParseException("invalid padding"); - } - } - - @Override - void optionToWire(DnsOutput out) { - out.writeU16(family); - out.writeU8(sourceNetmask); - out.writeU8(scopeNetmask); - out.writeByteArray(address.getAddress(), 0, (sourceNetmask + 7) / 8); - } - - @Override - String optionToString() { - StringBuilder sb = new StringBuilder(); - sb.append(address.getHostAddress()); - sb.append("/"); - sb.append(sourceNetmask); - sb.append(", scope netmask "); - sb.append(scopeNetmask); - return sb.toString(); - } - -} diff --git a/src/dorkbox/network/dns/records/DHCIDRecord.java b/src/dorkbox/network/dns/records/DHCIDRecord.java deleted file mode 100644 index 192782c0..00000000 --- a/src/dorkbox/network/dns/records/DHCIDRecord.java +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) 2008 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.util.Base64Fast; - -/** - * DHCID - Dynamic Host Configuration Protocol (DHCP) ID (RFC 4701) - * - * @author Brian Wellington - */ - -public -class DHCIDRecord extends DnsRecord { - - private static final long serialVersionUID = -8214820200808997707L; - - private byte[] data; - - DHCIDRecord() {} - - @Override - DnsRecord getObject() { - return new DHCIDRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - data = in.readByteArray(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeByteArray(data); - } - - @Override - void rrToString(StringBuilder sb) { - sb.append(Base64Fast.encode2(data)); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - data = st.getBase64(); - } - - /** - * Creates an DHCID Record from the given data - * - * @param data The binary data, which is opaque to DNS. - */ - public - DHCIDRecord(Name name, int dclass, long ttl, byte[] data) { - super(name, DnsRecordType.DHCID, dclass, ttl); - this.data = data; - } - - /** - * Returns the binary data. - */ - public - byte[] getData() { - return data; - } - -} diff --git a/src/dorkbox/network/dns/records/DLVRecord.java b/src/dorkbox/network/dns/records/DLVRecord.java deleted file mode 100644 index fbab2d71..00000000 --- a/src/dorkbox/network/dns/records/DLVRecord.java +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) 2002-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.network.dns.utils.base16; - -/** - * DLV - contains a Delegation Lookaside Validation record, which acts - * as the equivalent of a DS record in a lookaside zone. - * - * @author David Blacka - * @author Brian Wellington - * @see DNSSEC - * @see DSRecord - */ - -public -class DLVRecord extends DnsRecord { - - public static final int SHA1_DIGEST_ID = DSRecord.Digest.SHA1; - public static final int SHA256_DIGEST_ID = DSRecord.Digest.SHA1; - - private static final long serialVersionUID = 1960742375677534148L; - - private int footprint; - private int alg; - private int digestid; - private byte[] digest; - - DLVRecord() {} - - @Override - DnsRecord getObject() { - return new DLVRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - footprint = in.readU16(); - alg = in.readU8(); - digestid = in.readU8(); - digest = in.readByteArray(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU16(footprint); - out.writeU8(alg); - out.writeU8(digestid); - if (digest != null) { - out.writeByteArray(digest); - } - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(footprint); - sb.append(" "); - sb.append(alg); - sb.append(" "); - sb.append(digestid); - if (digest != null) { - sb.append(" "); - sb.append(base16.toString(digest)); - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - footprint = st.getUInt16(); - alg = st.getUInt8(); - digestid = st.getUInt8(); - digest = st.getHex(); - } - - /** - * Creates a DLV Record from the given data - * - * @param footprint The original KEY record's footprint (keyid). - * @param alg The original key algorithm. - * @param digestid The digest id code. - * @param digest A hash of the original key. - */ - public - DLVRecord(Name name, int dclass, long ttl, int footprint, int alg, int digestid, byte[] digest) { - super(name, DnsRecordType.DLV, dclass, ttl); - this.footprint = checkU16("footprint", footprint); - this.alg = checkU8("alg", alg); - this.digestid = checkU8("digestid", digestid); - this.digest = digest; - } - - /** - * Returns the key's algorithm. - */ - public - int getAlgorithm() { - return alg; - } - - /** - * Returns the key's Digest ID. - */ - public - int getDigestID() { - return digestid; - } - - /** - * Returns the binary hash of the key. - */ - public - byte[] getDigest() { - return digest; - } - - /** - * Returns the key's footprint. - */ - public - int getFootprint() { - return footprint; - } - -} diff --git a/src/dorkbox/network/dns/records/DNAMERecord.java b/src/dorkbox/network/dns/records/DNAMERecord.java deleted file mode 100644 index 80bbf480..00000000 --- a/src/dorkbox/network/dns/records/DNAMERecord.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * DNAME Record - maps a nonterminal alias (subtree) to a different domain - * - * @author Brian Wellington - */ - -public -class DNAMERecord extends SingleNameBase { - - private static final long serialVersionUID = 2670767677200844154L; - - DNAMERecord() {} - - @Override - DnsRecord getObject() { - return new DNAMERecord(); - } - - /** - * Creates a new DNAMERecord with the given data - * - * @param alias The name to which the DNAME alias points - */ - public - DNAMERecord(Name name, int dclass, long ttl, Name alias) { - super(name, DnsRecordType.DNAME, dclass, ttl, alias, "alias"); - } - - /** - * Gets the target of the DNAME Record - */ - public - Name getTarget() { - return getSingleName(); - } - - /** - * Gets the alias specified by the DNAME Record - */ - public - Name getAlias() { - return getSingleName(); - } - -} diff --git a/src/dorkbox/network/dns/records/DNSKEYRecord.java b/src/dorkbox/network/dns/records/DNSKEYRecord.java deleted file mode 100644 index ed648bcc..00000000 --- a/src/dorkbox/network/dns/records/DNSKEYRecord.java +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.security.PublicKey; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Key - contains a cryptographic public key for use by DNS. - * The data can be converted to objects implementing - * java.security.interfaces.PublicKey - * - * @author Brian Wellington - * @see DNSSEC - */ - -public -class DNSKEYRecord extends KEYBase { - - private static final long serialVersionUID = -8679800040426675002L; - - - public static - class Protocol { - /** - * Key will be used for DNSSEC - */ - public static final int DNSSEC = 3; - - private - Protocol() {} - } - - - public static - class Flags { - /** - * Key is a zone key - */ - public static final int ZONE_KEY = 0x100; - /** - * Key is a secure entry point key - */ - public static final int SEP_KEY = 0x1; - /** - * Key has been revoked - */ - public static final int REVOKE = 0x80; - - private - Flags() {} - } - - DNSKEYRecord() {} - - @Override - DnsRecord getObject() { - return new DNSKEYRecord(); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - flags = st.getUInt16(); - proto = st.getUInt8(); - String algString = st.getString(); - alg = DNSSEC.Algorithm.value(algString); - if (alg < 0) { - throw st.exception("Invalid algorithm: " + algString); - } - key = st.getBase64(); - } - - /** - * Creates a DNSKEY Record from the given data - * - * @param flags Flags describing the key's properties - * @param proto The protocol that the key was created for - * @param alg The key's algorithm - * @param key Binary representation of the key - */ - public - DNSKEYRecord(Name name, int dclass, long ttl, int flags, int proto, int alg, byte[] key) { - super(name, DnsRecordType.DNSKEY, dclass, ttl, flags, proto, alg, key); - } - - /** - * Creates a DNSKEY Record from the given data - * - * @param flags Flags describing the key's properties - * @param proto The protocol that the key was created for - * @param alg The key's algorithm - * @param key The key as a PublicKey - * - * @throws DNSSEC.DNSSECException The PublicKey could not be converted into DNS - * format. - */ - public - DNSKEYRecord(Name name, int dclass, long ttl, int flags, int proto, int alg, PublicKey key) throws DNSSEC.DNSSECException { - super(name, DnsRecordType.DNSKEY, dclass, ttl, flags, proto, alg, DNSSEC.fromPublicKey(key, alg)); - publicKey = key; - } - -} diff --git a/src/dorkbox/network/dns/records/DNSSEC.java b/src/dorkbox/network/dns/records/DNSSEC.java deleted file mode 100644 index a2706419..00000000 --- a/src/dorkbox/network/dns/records/DNSSEC.java +++ /dev/null @@ -1,1278 +0,0 @@ -// Copyright (c) 1999-2010 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.math.BigInteger; -import java.security.GeneralSecurityException; -import java.security.KeyFactory; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.Signature; -import java.security.interfaces.DSAPrivateKey; -import java.security.interfaces.DSAPublicKey; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.DSAPublicKeySpec; -import java.security.spec.ECFieldFp; -import java.security.spec.ECParameterSpec; -import java.security.spec.ECPoint; -import java.security.spec.ECPublicKeySpec; -import java.security.spec.EllipticCurve; -import java.security.spec.RSAPublicKeySpec; -import java.util.Arrays; -import java.util.Date; -import java.util.Iterator; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Mnemonic; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsSection; - -/** - * Constants and methods relating to DNSSEC. - *

- * DNSSEC provides authentication for DNS information. - * - * @author Brian Wellington - * @see RRSIGRecord - * @see DNSKEYRecord - * @see RRset - */ - -public -class DNSSEC { - - // RFC 4357 DnsSection 11.4 - private static final ECKeyInfo GOST = new ECKeyInfo(32, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94", - "A6", - "1", - "8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893"); - // RFC 5114 DnsSection 2.6 - private static final ECKeyInfo ECDSA_P256 = new ECKeyInfo(32, - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", - "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", - "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", - "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", - "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"); - // RFC 5114 DnsSection 2.7 - private static final ECKeyInfo ECDSA_P384 = new ECKeyInfo(48, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", - "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", - "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", - "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"); - private static final int ASN1_SEQ = 0x30; - private static final int ASN1_INT = 0x2; - private static final int DSA_LEN = 20; - - - public static - class Algorithm { - /** - * RSA/MD5 public key (deprecated) - */ - public static final int RSAMD5 = 1; - /** - * Diffie Hellman key - */ - public static final int DH = 2; - /** - * DSA public key - */ - public static final int DSA = 3; - /** - * RSA/SHA1 public key - */ - public static final int RSASHA1 = 5; - /** - * DSA/SHA1, NSEC3-aware public key - */ - public static final int DSA_NSEC3_SHA1 = 6; - /** - * RSA/SHA1, NSEC3-aware public key - */ - public static final int RSA_NSEC3_SHA1 = 7; - /** - * RSA/SHA256 public key - */ - public static final int RSASHA256 = 8; - /** - * RSA/SHA512 public key - */ - public static final int RSASHA512 = 10; - /** - * GOST R 34.10-2001. - * This requires an external cryptography provider, - * such as BouncyCastle. - */ - public static final int ECC_GOST = 12; - /** - * ECDSA Curve P-256 with SHA-256 public key - **/ - public static final int ECDSAP256SHA256 = 13; - /** - * ECDSA Curve P-384 with SHA-384 public key - **/ - public static final int ECDSAP384SHA384 = 14; - /** - * Indirect keys; the actual key is elsewhere. - */ - public static final int INDIRECT = 252; - /** - * Private algorithm, specified by domain name - */ - public static final int PRIVATEDNS = 253; - /** - * Private algorithm, specified by OID - */ - public static final int PRIVATEOID = 254; - private static Mnemonic algs = new Mnemonic("DNSSEC algorithm", Mnemonic.CASE_UPPER); - - private - Algorithm() {} - - static { - algs.setMaximum(0xFF); - algs.setNumericAllowed(true); - - algs.add(RSAMD5, "RSAMD5"); - algs.add(DH, "DH"); - algs.add(DSA, "DSA"); - algs.add(RSASHA1, "RSASHA1"); - algs.add(DSA_NSEC3_SHA1, "DSA-NSEC3-SHA1"); - algs.add(RSA_NSEC3_SHA1, "RSA-NSEC3-SHA1"); - algs.add(RSASHA256, "RSASHA256"); - algs.add(RSASHA512, "RSASHA512"); - algs.add(ECC_GOST, "ECC-GOST"); - algs.add(ECDSAP256SHA256, "ECDSAP256SHA256"); - algs.add(ECDSAP384SHA384, "ECDSAP384SHA384"); - algs.add(INDIRECT, "INDIRECT"); - algs.add(PRIVATEDNS, "PRIVATEDNS"); - algs.add(PRIVATEOID, "PRIVATEOID"); - } - - /** - * Converts an algorithm into its textual representation - */ - public static - String string(int alg) { - return algs.getText(alg); - } - - /** - * Converts a textual representation of an algorithm into its numeric - * code. Integers in the range 0..255 are also accepted. - * - * @param s The textual representation of the algorithm - * - * @return The algorithm code, or -1 on error. - */ - public static - int value(String s) { - return algs.getValue(s); - } - } - - - private - DNSSEC() { } - - /** - * Creates a byte array containing the concatenation of the fields of the - * SIG(0) record and the message to be signed. This does not perform - * a cryptographic digest. - * - * @param sig The SIG record used to sign the rrset. - * @param msg The message to be signed. - * @param previous If this is a response, the signature from the query. - * - * @return The data to be cryptographically signed. - */ - public static - byte[] digestMessage(SIGRecord sig, DnsMessage msg, byte[] previous) { - DnsOutput out = new DnsOutput(); - digestSIG(out, sig); - - if (previous != null) { - out.writeByteArray(previous); - } - - msg.toWire(out); - return out.toByteArray(); - } - - private static - void digestSIG(DnsOutput out, SIGBase sig) { - out.writeU16(sig.getTypeCovered()); - out.writeU8(sig.getAlgorithm()); - out.writeU8(sig.getLabels()); - out.writeU32(sig.getOrigTTL()); - out.writeU32(sig.getExpire() - .getTime() / 1000); - out.writeU32(sig.getTimeSigned() - .getTime() / 1000); - out.writeU16(sig.getFootprint()); - sig.getSigner() - .toWireCanonical(out); - } - - - /** - * A DNSSEC exception. - */ - public static - class DNSSECException extends Exception { - DNSSECException(String s) { - super(s); - } - } - - - /** - * An algorithm is unsupported by this DNSSEC implementation. - */ - public static - class UnsupportedAlgorithmException extends DNSSECException { - UnsupportedAlgorithmException(int alg) { - super("Unsupported algorithm: " + alg); - } - } - - - /** - * The cryptographic data in a DNSSEC key is malformed. - */ - public static - class MalformedKeyException extends DNSSECException { - MalformedKeyException(KEYBase rec) { - super("Invalid key data: " + asString(rec)); - } - - private static - String asString(final KEYBase rec) { - StringBuilder stringBuilder = new StringBuilder(); - rec.rdataToString(stringBuilder); - return stringBuilder.toString(); - } - } - - - /** - * A DNSSEC verification failed because fields in the DNSKEY and RRSIG records - * do not match. - */ - public static - class KeyMismatchException extends DNSSECException { - private KEYBase key; - private SIGBase sig; - - KeyMismatchException(KEYBase key, SIGBase sig) { - super("key " + key.getName() + "/" + DNSSEC.Algorithm.string(key.getAlgorithm()) + "/" + key.getFootprint() + " " + - "does not match signature " + sig.getSigner() + "/" + DNSSEC.Algorithm.string(sig.getAlgorithm()) + "/" + - sig.getFootprint()); - } - } - - - /** - * A DNSSEC verification failed because the signature has expired. - */ - public static - class SignatureExpiredException extends DNSSECException { - private Date when, now; - - SignatureExpiredException(Date when, Date now) { - super("signature expired"); - this.when = when; - this.now = now; - } - - /** - * @return When the signature expired - */ - public - Date getExpiration() { - return when; - } - - /** - * @return When the verification was attempted - */ - public - Date getVerifyTime() { - return now; - } - } - - - /** - * A DNSSEC verification failed because the signature has not yet become valid. - */ - public static - class SignatureNotYetValidException extends DNSSECException { - private Date when, now; - - SignatureNotYetValidException(Date when, Date now) { - super("signature is not yet valid"); - this.when = when; - this.now = now; - } - - /** - * @return When the signature will become valid - */ - public - Date getExpiration() { - return when; - } - - /** - * @return When the verification was attempted - */ - public - Date getVerifyTime() { - return now; - } - } - - - /** - * A DNSSEC verification failed because the cryptographic signature - * verification failed. - */ - public static - class SignatureVerificationException extends DNSSECException { - SignatureVerificationException() { - super("signature verification failed"); - } - } - - - /** - * The key data provided is inconsistent. - */ - public static - class IncompatibleKeyException extends IllegalArgumentException { - IncompatibleKeyException() { - super("incompatible keys"); - } - } - - - /** - * No signature was found. - */ - public static - class NoSignatureException extends DNSSECException { - NoSignatureException() { - super("no signature found"); - } - } - - private static - byte[] trimByteArray(byte[] array) { - if (array[0] == 0) { - byte trimmedArray[] = new byte[array.length - 1]; - System.arraycopy(array, 1, trimmedArray, 0, array.length - 1); - return trimmedArray; - } - else { - return array; - } - } - - private static - void writeBigInteger(DnsOutput out, BigInteger val) { - byte[] b = trimByteArray(val.toByteArray()); - out.writeByteArray(b); - } - - private static - void writePaddedBigInteger(DnsOutput out, BigInteger val, int len) { - byte[] b = trimByteArray(val.toByteArray()); - - if (b.length > len) { - throw new IllegalArgumentException(); - } - - if (b.length < len) { - byte[] pad = new byte[len - b.length]; - out.writeByteArray(pad); - } - - out.writeByteArray(b); - } - - private static - void writePaddedBigIntegerLittleEndian(DnsOutput out, BigInteger val, int len) { - byte[] b = trimByteArray(val.toByteArray()); - - if (b.length > len) { - throw new IllegalArgumentException(); - } - - reverseByteArray(b); - out.writeByteArray(b); - - if (b.length < len) { - byte[] pad = new byte[len - b.length]; - out.writeByteArray(pad); - } - } - - - private static - class ECKeyInfo { - int length; - public BigInteger p, a, b, gx, gy, n; - EllipticCurve curve; - ECParameterSpec spec; - - ECKeyInfo(int length, String p_str, String a_str, String b_str, String gx_str, String gy_str, String n_str) { - this.length = length; - p = new BigInteger(p_str, 16); - a = new BigInteger(a_str, 16); - b = new BigInteger(b_str, 16); - gx = new BigInteger(gx_str, 16); - gy = new BigInteger(gy_str, 16); - n = new BigInteger(n_str, 16); - curve = new EllipticCurve(new ECFieldFp(p), a, b); - spec = new ECParameterSpec(curve, new ECPoint(gx, gy), n, 1); - } - } - - /** - * Converts a KEY/DNSKEY record into a PublicKey - */ - static - PublicKey toPublicKey(KEYBase r) throws DNSSECException { - int alg = r.getAlgorithm(); - try { - switch (alg) { - case Algorithm.RSAMD5: - case Algorithm.RSASHA1: - case Algorithm.RSA_NSEC3_SHA1: - case Algorithm.RSASHA256: - case Algorithm.RSASHA512: - return toRSAPublicKey(r); - case Algorithm.DSA: - case Algorithm.DSA_NSEC3_SHA1: - return toDSAPublicKey(r); - case Algorithm.ECC_GOST: - return toECGOSTPublicKey(r, GOST); - case Algorithm.ECDSAP256SHA256: - return toECDSAPublicKey(r, ECDSA_P256); - case Algorithm.ECDSAP384SHA384: - return toECDSAPublicKey(r, ECDSA_P384); - default: - throw new UnsupportedAlgorithmException(alg); - } - } catch (IOException e) { - throw new MalformedKeyException(r); - } catch (GeneralSecurityException e) { - throw new DNSSECException(e.toString()); - } - } - - private static - PublicKey toRSAPublicKey(KEYBase r) throws IOException, GeneralSecurityException { - DnsInput in = new DnsInput(r.getKey()); - int exponentLength = in.readU8(); - if (exponentLength == 0) { - exponentLength = in.readU16(); - } - BigInteger exponent = readBigInteger(in, exponentLength); - BigInteger modulus = readBigInteger(in); - - KeyFactory factory = KeyFactory.getInstance("RSA"); - return factory.generatePublic(new RSAPublicKeySpec(modulus, exponent)); - } - - private static - BigInteger readBigInteger(DnsInput in, int len) throws IOException { - byte[] b = in.readByteArray(len); - return new BigInteger(1, b); - } - - private static - BigInteger readBigInteger(DnsInput in) { - byte[] b = in.readByteArray(); - return new BigInteger(1, b); - } - - private static - PublicKey toDSAPublicKey(KEYBase r) throws IOException, GeneralSecurityException, MalformedKeyException { - DnsInput in = new DnsInput(r.getKey()); - - int t = in.readU8(); - if (t > 8) { - throw new MalformedKeyException(r); - } - - BigInteger q = readBigInteger(in, 20); - BigInteger p = readBigInteger(in, 64 + t * 8); - BigInteger g = readBigInteger(in, 64 + t * 8); - BigInteger y = readBigInteger(in, 64 + t * 8); - - KeyFactory factory = KeyFactory.getInstance("DSA"); - return factory.generatePublic(new DSAPublicKeySpec(y, p, q, g)); - } - - private static - PublicKey toECGOSTPublicKey(KEYBase r, ECKeyInfo keyinfo) throws IOException, GeneralSecurityException, MalformedKeyException { - DnsInput in = new DnsInput(r.getKey()); - - BigInteger x = readBigIntegerLittleEndian(in, keyinfo.length); - BigInteger y = readBigIntegerLittleEndian(in, keyinfo.length); - ECPoint q = new ECPoint(x, y); - - KeyFactory factory = KeyFactory.getInstance("ECGOST3410"); - return factory.generatePublic(new ECPublicKeySpec(q, keyinfo.spec)); - } - - private static - BigInteger readBigIntegerLittleEndian(DnsInput in, int len) throws IOException { - byte[] b = in.readByteArray(len); - reverseByteArray(b); - return new BigInteger(1, b); - } - - private static - void reverseByteArray(byte[] array) { - for (int i = 0; i < array.length / 2; i++) { - int j = array.length - i - 1; - byte tmp = array[i]; - array[i] = array[j]; - array[j] = tmp; - } - } - - private static - PublicKey toECDSAPublicKey(KEYBase r, ECKeyInfo keyinfo) throws IOException, GeneralSecurityException, MalformedKeyException { - DnsInput in = new DnsInput(r.getKey()); - - // RFC 6605 DnsSection 4 - BigInteger x = readBigInteger(in, keyinfo.length); - BigInteger y = readBigInteger(in, keyinfo.length); - ECPoint q = new ECPoint(x, y); - - KeyFactory factory = KeyFactory.getInstance("EC"); - return factory.generatePublic(new ECPublicKeySpec(q, keyinfo.spec)); - } - - private static - byte[] fromRSAPublicKey(RSAPublicKey key) { - DnsOutput out = new DnsOutput(); - BigInteger exponent = key.getPublicExponent(); - BigInteger modulus = key.getModulus(); - int exponentLength = BigIntegerLength(exponent); - - if (exponentLength < 256) { - out.writeU8(exponentLength); - } - else { - out.writeU8(0); - out.writeU16(exponentLength); - } - writeBigInteger(out, exponent); - writeBigInteger(out, modulus); - - return out.toByteArray(); - } - - private static - byte[] fromDSAPublicKey(DSAPublicKey key) { - DnsOutput out = new DnsOutput(); - BigInteger q = key.getParams() - .getQ(); - BigInteger p = key.getParams() - .getP(); - BigInteger g = key.getParams() - .getG(); - BigInteger y = key.getY(); - int t = (p.toByteArray().length - 64) / 8; - - out.writeU8(t); - writeBigInteger(out, q); - writeBigInteger(out, p); - writePaddedBigInteger(out, g, 8 * t + 64); - writePaddedBigInteger(out, y, 8 * t + 64); - - return out.toByteArray(); - } - - private static - byte[] fromECGOSTPublicKey(ECPublicKey key, ECKeyInfo keyinfo) { - DnsOutput out = new DnsOutput(); - - BigInteger x = key.getW() - .getAffineX(); - BigInteger y = key.getW() - .getAffineY(); - - writePaddedBigIntegerLittleEndian(out, x, keyinfo.length); - writePaddedBigIntegerLittleEndian(out, y, keyinfo.length); - - return out.toByteArray(); - } - - private static - byte[] fromECDSAPublicKey(ECPublicKey key, ECKeyInfo keyinfo) { - DnsOutput out = new DnsOutput(); - - BigInteger x = key.getW() - .getAffineX(); - BigInteger y = key.getW() - .getAffineY(); - - writePaddedBigInteger(out, x, keyinfo.length); - writePaddedBigInteger(out, y, keyinfo.length); - - return out.toByteArray(); - } - - /** - * Builds a DNSKEY record from a PublicKey - */ - static - byte[] fromPublicKey(PublicKey key, int alg) throws DNSSECException { - switch (alg) { - case Algorithm.RSAMD5: - case Algorithm.RSASHA1: - case Algorithm.RSA_NSEC3_SHA1: - case Algorithm.RSASHA256: - case Algorithm.RSASHA512: - if (!(key instanceof RSAPublicKey)) { - throw new IncompatibleKeyException(); - } - return fromRSAPublicKey((RSAPublicKey) key); - case Algorithm.DSA: - case Algorithm.DSA_NSEC3_SHA1: - if (!(key instanceof DSAPublicKey)) { - throw new IncompatibleKeyException(); - } - return fromDSAPublicKey((DSAPublicKey) key); - case Algorithm.ECC_GOST: - if (!(key instanceof ECPublicKey)) { - throw new IncompatibleKeyException(); - } - return fromECGOSTPublicKey((ECPublicKey) key, GOST); - case Algorithm.ECDSAP256SHA256: - if (!(key instanceof ECPublicKey)) { - throw new IncompatibleKeyException(); - } - return fromECDSAPublicKey((ECPublicKey) key, ECDSA_P256); - case Algorithm.ECDSAP384SHA384: - if (!(key instanceof ECPublicKey)) { - throw new IncompatibleKeyException(); - } - return fromECDSAPublicKey((ECPublicKey) key, ECDSA_P384); - default: - throw new UnsupportedAlgorithmException(alg); - } - } - - /** - * Verify a DNSSEC signature. - * - * @param rrset The data to be verified. - * @param rrsig The RRSIG record containing the signature. - * @param key The DNSKEY record to verify the signature with. - * - * @throws UnsupportedAlgorithmException The algorithm is unknown - * @throws MalformedKeyException The key is malformed - * @throws KeyMismatchException The key and signature do not match - * @throws SignatureExpiredException The signature has expired - * @throws SignatureNotYetValidException The signature is not yet valid - * @throws SignatureVerificationException The signature does not verify. - * @throws DNSSECException Some other error occurred. - */ - public static - void verify(RRset rrset, RRSIGRecord rrsig, DNSKEYRecord key) throws DNSSECException { - if (!matches(rrsig, key)) { - throw new KeyMismatchException(key, rrsig); - } - - Date now = new Date(); - if (now.compareTo(rrsig.getExpire()) > 0) { - throw new SignatureExpiredException(rrsig.getExpire(), now); - } - if (now.compareTo(rrsig.getTimeSigned()) < 0) { - throw new SignatureNotYetValidException(rrsig.getTimeSigned(), now); - } - - verify(key.getPublicKey(), rrsig.getAlgorithm(), digestRRset(rrsig, rrset), rrsig.getSignature()); - } - - /** - * Creates a byte array containing the concatenation of the fields of the - * SIG record and the RRsets to be signed/verified. This does not perform - * a cryptographic digest. - * - * @param rrsig The RRSIG record used to sign/verify the rrset. - * @param rrset The data to be signed/verified. - * - * @return The data to be cryptographically signed or verified. - */ - public static - byte[] digestRRset(RRSIGRecord rrsig, RRset rrset) { - DnsOutput out = new DnsOutput(); - digestSIG(out, rrsig); - - int size = rrset.size(); - DnsRecord[] records = new DnsRecord[size]; - - Iterator it = rrset.rrs(); - Name name = rrset.getName(); - Name wild = null; - int sigLabels = rrsig.getLabels() + 1; // Add the root label back. - if (name.labels() > sigLabels) { - wild = name.wild(name.labels() - sigLabels); - } - while (it.hasNext()) { - records[--size] = (DnsRecord) it.next(); - } - Arrays.sort(records); - - DnsOutput header = new DnsOutput(); - if (wild != null) { - wild.toWireCanonical(header); - } - else { - name.toWireCanonical(header); - } - header.writeU16(rrset.getType()); - header.writeU16(rrset.getDClass()); - header.writeU32(rrsig.getOrigTTL()); - for (int i = 0; i < records.length; i++) { - out.writeByteArray(header.toByteArray()); - int lengthPosition = out.current(); - out.writeU16(0); - out.writeByteArray(records[i].rdataToWireCanonical()); - int rrlength = out.current() - lengthPosition - 2; - out.save(); - out.jump(lengthPosition); - out.writeU16(rrlength); - out.restore(); - } - return out.toByteArray(); - } - - private static - void verify(PublicKey key, int alg, byte[] data, byte[] signature) throws DNSSECException { - if (key instanceof DSAPublicKey) { - try { - signature = DSASignaturefromDNS(signature); - } catch (IOException e) { - throw new IllegalStateException(); - } - } - else if (key instanceof ECPublicKey) { - try { - switch (alg) { - case Algorithm.ECC_GOST: - signature = ECGOSTSignaturefromDNS(signature, GOST); - break; - case Algorithm.ECDSAP256SHA256: - signature = ECDSASignaturefromDNS(signature, ECDSA_P256); - break; - case Algorithm.ECDSAP384SHA384: - signature = ECDSASignaturefromDNS(signature, ECDSA_P384); - break; - default: - throw new UnsupportedAlgorithmException(alg); - } - } catch (IOException e) { - throw new IllegalStateException(); - } - } - - try { - Signature s = Signature.getInstance(algString(alg)); - s.initVerify(key); - s.update(data); - if (!s.verify(signature)) { - throw new SignatureVerificationException(); - } - } catch (GeneralSecurityException e) { - throw new DNSSECException(e.toString()); - } - } - - /** - * Convert an algorithm number to the corresponding JCA string. - * - * @param alg The algorithm number. - * - * @throws UnsupportedAlgorithmException The algorithm is unknown. - */ - public static - String algString(int alg) throws UnsupportedAlgorithmException { - switch (alg) { - case Algorithm.RSAMD5: - return "MD5withRSA"; - case Algorithm.DSA: - case Algorithm.DSA_NSEC3_SHA1: - return "SHA1withDSA"; - case Algorithm.RSASHA1: - case Algorithm.RSA_NSEC3_SHA1: - return "SHA1withRSA"; - case Algorithm.RSASHA256: - return "SHA256withRSA"; - case Algorithm.RSASHA512: - return "SHA512withRSA"; - case Algorithm.ECC_GOST: - return "GOST3411withECGOST3410"; - case Algorithm.ECDSAP256SHA256: - return "SHA256withECDSA"; - case Algorithm.ECDSAP384SHA384: - return "SHA384withECDSA"; - default: - throw new UnsupportedAlgorithmException(alg); - } - } - - private static - byte[] DSASignaturefromDNS(byte[] dns) throws DNSSECException, IOException { - if (dns.length != 1 + DSA_LEN * 2) { - throw new SignatureVerificationException(); - } - - DnsInput in = new DnsInput(dns); - DnsOutput out = new DnsOutput(); - - int t = in.readU8(); - - byte[] r = in.readByteArray(DSA_LEN); - int rlen = DSA_LEN; - if (r[0] < 0) { - rlen++; - } - - byte[] s = in.readByteArray(DSA_LEN); - int slen = DSA_LEN; - if (s[0] < 0) { - slen++; - } - - out.writeU8(ASN1_SEQ); - out.writeU8(rlen + slen + 4); - - out.writeU8(ASN1_INT); - out.writeU8(rlen); - if (rlen > DSA_LEN) { - out.writeU8(0); - } - out.writeByteArray(r); - - out.writeU8(ASN1_INT); - out.writeU8(slen); - if (slen > DSA_LEN) { - out.writeU8(0); - } - out.writeByteArray(s); - - return out.toByteArray(); - } - - private static - byte[] ECGOSTSignaturefromDNS(byte[] signature, ECKeyInfo keyinfo) throws DNSSECException, IOException { - if (signature.length != keyinfo.length * 2) { - throw new SignatureVerificationException(); - } - // Wire format is equal to the engine input - return signature; - } - - private static - byte[] ECDSASignaturefromDNS(byte[] signature, ECKeyInfo keyinfo) throws DNSSECException, IOException { - if (signature.length != keyinfo.length * 2) { - throw new SignatureVerificationException(); - } - - DnsInput in = new DnsInput(signature); - DnsOutput out = new DnsOutput(); - - byte[] r = in.readByteArray(keyinfo.length); - int rlen = keyinfo.length; - if (r[0] < 0) { - rlen++; - } - - byte[] s = in.readByteArray(keyinfo.length); - int slen = keyinfo.length; - if (s[0] < 0) { - slen++; - } - - out.writeU8(ASN1_SEQ); - out.writeU8(rlen + slen + 4); - - out.writeU8(ASN1_INT); - out.writeU8(rlen); - if (rlen > keyinfo.length) { - out.writeU8(0); - } - out.writeByteArray(r); - - out.writeU8(ASN1_INT); - out.writeU8(slen); - if (slen > keyinfo.length) { - out.writeU8(0); - } - out.writeByteArray(s); - - return out.toByteArray(); - } - - private static - boolean matches(SIGBase sig, KEYBase key) { - return (key.getAlgorithm() == sig.getAlgorithm() && key.getFootprint() == sig.getFootprint() && key.getName() - .equals(sig.getSigner())); - } - - /** - * Generate a DNSSEC signature. key and privateKey must refer to the - * same underlying cryptographic key. - * - * @param rrset The data to be signed - * @param key The DNSKEY record to use as part of signing - * @param privkey The PrivateKey to use when signing - * @param inception The time at which the signatures should become valid - * @param expiration The time at which the signatures should expire - * - * @return The generated signature - * - * @throws UnsupportedAlgorithmException The algorithm is unknown - * @throws MalformedKeyException The key is malformed - * @throws DNSSECException Some other error occurred. - */ - public static - RRSIGRecord sign(RRset rrset, DNSKEYRecord key, PrivateKey privkey, Date inception, Date expiration) throws DNSSECException { - return sign(rrset, key, privkey, inception, expiration, null); - } - - /** - * Generate a DNSSEC signature. key and privateKey must refer to the - * same underlying cryptographic key. - * - * @param rrset The data to be signed - * @param key The DNSKEY record to use as part of signing - * @param privkey The PrivateKey to use when signing - * @param inception The time at which the signatures should become valid - * @param expiration The time at which the signatures should expire - * @param provider The name of the JCA provider. If non-null, it will be - * passed to JCA getInstance() methods. - * - * @return The generated signature - * - * @throws UnsupportedAlgorithmException The algorithm is unknown - * @throws MalformedKeyException The key is malformed - * @throws DNSSECException Some other error occurred. - */ - public static - RRSIGRecord sign(RRset rrset, DNSKEYRecord key, PrivateKey privkey, Date inception, Date expiration, String provider) - throws DNSSECException { - int alg = key.getAlgorithm(); - checkAlgorithm(privkey, alg); - - RRSIGRecord rrsig = new RRSIGRecord(rrset.getName(), - rrset.getDClass(), - rrset.getTTL(), - rrset.getType(), - alg, - rrset.getTTL(), - expiration, - inception, - key.getFootprint(), - key.getName(), - null); - - rrsig.setSignature(sign(privkey, key.getPublicKey(), alg, digestRRset(rrsig, rrset), provider)); - return rrsig; - } - - private static - byte[] sign(PrivateKey privkey, PublicKey pubkey, int alg, byte[] data, String provider) throws DNSSECException { - byte[] signature; - try { - Signature s; - if (provider != null) { - s = Signature.getInstance(algString(alg), provider); - } - else { - s = Signature.getInstance(algString(alg)); - } - s.initSign(privkey); - s.update(data); - signature = s.sign(); - } catch (GeneralSecurityException e) { - throw new DNSSECException(e.toString()); - } - - if (pubkey instanceof DSAPublicKey) { - try { - DSAPublicKey dsa = (DSAPublicKey) pubkey; - BigInteger P = dsa.getParams() - .getP(); - int t = (BigIntegerLength(P) - 64) / 8; - signature = DSASignaturetoDNS(signature, t); - } catch (IOException e) { - throw new IllegalStateException(); - } - } - else if (pubkey instanceof ECPublicKey) { - try { - switch (alg) { - case Algorithm.ECC_GOST: - // Wire format is equal to the engine output - break; - case Algorithm.ECDSAP256SHA256: - signature = ECDSASignaturetoDNS(signature, ECDSA_P256); - break; - case Algorithm.ECDSAP384SHA384: - signature = ECDSASignaturetoDNS(signature, ECDSA_P384); - break; - default: - throw new UnsupportedAlgorithmException(alg); - } - } catch (IOException e) { - throw new IllegalStateException(); - } - } - - return signature; - } - - private static - int BigIntegerLength(BigInteger i) { - return (i.bitLength() + 7) / 8; - } - - private static - byte[] DSASignaturetoDNS(byte[] signature, int t) throws IOException { - DnsInput in = new DnsInput(signature); - DnsOutput out = new DnsOutput(); - - out.writeU8(t); - - int tmp = in.readU8(); - if (tmp != ASN1_SEQ) { - throw new IOException(); - } - int seqlen = in.readU8(); - - tmp = in.readU8(); - if (tmp != ASN1_INT) { - throw new IOException(); - } - int rlen = in.readU8(); - if (rlen == DSA_LEN + 1) { - if (in.readU8() != 0) { - throw new IOException(); - } - } - else if (rlen != DSA_LEN) { - throw new IOException(); - } - byte[] bytes = in.readByteArray(DSA_LEN); - out.writeByteArray(bytes); - - tmp = in.readU8(); - if (tmp != ASN1_INT) { - throw new IOException(); - } - int slen = in.readU8(); - if (slen == DSA_LEN + 1) { - if (in.readU8() != 0) { - throw new IOException(); - } - } - else if (slen != DSA_LEN) { - throw new IOException(); - } - bytes = in.readByteArray(DSA_LEN); - out.writeByteArray(bytes); - - return out.toByteArray(); - } - - private static - byte[] ECDSASignaturetoDNS(byte[] signature, ECKeyInfo keyinfo) throws IOException { - DnsInput in = new DnsInput(signature); - DnsOutput out = new DnsOutput(); - - int tmp = in.readU8(); - if (tmp != ASN1_SEQ) { - throw new IOException(); - } - int seqlen = in.readU8(); - - tmp = in.readU8(); - if (tmp != ASN1_INT) { - throw new IOException(); - } - int rlen = in.readU8(); - if (rlen == keyinfo.length + 1) { - if (in.readU8() != 0) { - throw new IOException(); - } - } - else if (rlen != keyinfo.length) { - throw new IOException(); - } - byte[] bytes = in.readByteArray(keyinfo.length); - out.writeByteArray(bytes); - - tmp = in.readU8(); - if (tmp != ASN1_INT) { - throw new IOException(); - } - int slen = in.readU8(); - if (slen == keyinfo.length + 1) { - if (in.readU8() != 0) { - throw new IOException(); - } - } - else if (slen != keyinfo.length) { - throw new IOException(); - } - bytes = in.readByteArray(keyinfo.length); - out.writeByteArray(bytes); - - return out.toByteArray(); - } - - static - void checkAlgorithm(PrivateKey key, int alg) throws UnsupportedAlgorithmException { - switch (alg) { - case Algorithm.RSAMD5: - case Algorithm.RSASHA1: - case Algorithm.RSA_NSEC3_SHA1: - case Algorithm.RSASHA256: - case Algorithm.RSASHA512: - if (!(key instanceof RSAPrivateKey)) { - throw new IncompatibleKeyException(); - } - break; - case Algorithm.DSA: - case Algorithm.DSA_NSEC3_SHA1: - if (!(key instanceof DSAPrivateKey)) { - throw new IncompatibleKeyException(); - } - break; - case Algorithm.ECC_GOST: - case Algorithm.ECDSAP256SHA256: - case Algorithm.ECDSAP384SHA384: - if (!(key instanceof ECPrivateKey)) { - throw new IncompatibleKeyException(); - } - break; - default: - throw new UnsupportedAlgorithmException(alg); - } - } - - static - SIGRecord signMessage(DnsMessage dnsMessage, SIGRecord previous, KEYRecord key, PrivateKey privkey, Date inception, Date expiration) - throws DNSSECException { - int alg = key.getAlgorithm(); - checkAlgorithm(privkey, alg); - - SIGRecord sig = new SIGRecord(Name.root, DnsClass.ANY, 0, 0, alg, 0, expiration, inception, key.getFootprint(), key.getName(), null); - DnsOutput out = new DnsOutput(); - digestSIG(out, sig); - if (previous != null) { - out.writeByteArray(previous.getSignature()); - } - out.writeByteArray(dnsMessage.toWire()); - - sig.setSignature(sign(privkey, key.getPublicKey(), alg, out.toByteArray(), null)); - return sig; - } - - static - void verifyMessage(DnsMessage dnsMessage, byte[] bytes, SIGRecord sig, SIGRecord previous, KEYRecord key) throws DNSSECException { - if (dnsMessage.sig0start == 0) { - throw new NoSignatureException(); - } - - if (!matches(sig, key)) { - throw new KeyMismatchException(key, sig); - } - - Date now = new Date(); - - if (now.compareTo(sig.getExpire()) > 0) { - throw new SignatureExpiredException(sig.getExpire(), now); - } - if (now.compareTo(sig.getTimeSigned()) < 0) { - throw new SignatureNotYetValidException(sig.getTimeSigned(), now); - } - - DnsOutput out = new DnsOutput(); - digestSIG(out, sig); - if (previous != null) { - out.writeByteArray(previous.getSignature()); - } - - Header header = (Header) dnsMessage.getHeader() - .clone(); - header.decCount(DnsSection.ADDITIONAL); - out.writeByteArray(header.toWire()); - - out.writeByteArray(bytes, Header.LENGTH, dnsMessage.sig0start - Header.LENGTH); - - verify(key.getPublicKey(), sig.getAlgorithm(), out.toByteArray(), sig.getSignature()); - } - - /** - * Generate the digest value for a DS key - * - * @param key Which is covered by the DS record - * @param digestid The type of digest - * - * @return The digest value as an array of bytes - */ - static - byte[] generateDSDigest(DNSKEYRecord key, int digestid) { - MessageDigest digest; - try { - switch (digestid) { - case DSRecord.Digest.SHA1: - digest = MessageDigest.getInstance("sha-1"); - break; - case DSRecord.Digest.SHA256: - digest = MessageDigest.getInstance("sha-256"); - break; - case DSRecord.Digest.GOST3411: - digest = MessageDigest.getInstance("GOST3411"); - break; - case DSRecord.Digest.SHA384: - digest = MessageDigest.getInstance("sha-384"); - break; - default: - throw new IllegalArgumentException("unknown DS digest type " + digestid); - } - } catch (NoSuchAlgorithmException e) { - throw new IllegalStateException("no message digest support"); - } - digest.update(key.getName() - .toWireCanonical()); - digest.update(key.rdataToWireCanonical()); - return digest.digest(); - } - -} diff --git a/src/dorkbox/network/dns/records/DSRecord.java b/src/dorkbox/network/dns/records/DSRecord.java deleted file mode 100644 index 598d5987..00000000 --- a/src/dorkbox/network/dns/records/DSRecord.java +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (c) 2002-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.network.dns.utils.base16; - -/** - * DS - contains a Delegation Signer record, which acts as a - * placeholder for KEY records in the parent zone. - * - * @author David Blacka - * @author Brian Wellington - * @see DNSSEC - */ - -public -class DSRecord extends DnsRecord { - - public static final int SHA1_DIGEST_ID = Digest.SHA1; - public static final int SHA256_DIGEST_ID = Digest.SHA256; - public static final int GOST3411_DIGEST_ID = Digest.GOST3411; - public static final int SHA384_DIGEST_ID = Digest.SHA384; - private static final long serialVersionUID = -9001819329700081493L; - private int footprint; - private int alg; - private int digestid; - private byte[] digest; - - - public static - class Digest { - /** - * SHA-1 - */ - public static final int SHA1 = 1; - /** - * SHA-256 - */ - public static final int SHA256 = 2; - /** - * GOST R 34.11-94 - */ - public static final int GOST3411 = 3; - /** - * SHA-384 - */ - public static final int SHA384 = 4; - - private - Digest() {} - } - - DSRecord() {} - - @Override - DnsRecord getObject() { - return new DSRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - footprint = in.readU16(); - alg = in.readU8(); - digestid = in.readU8(); - digest = in.readByteArray(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU16(footprint); - out.writeU8(alg); - out.writeU8(digestid); - if (digest != null) { - out.writeByteArray(digest); - } - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(footprint); - sb.append(" "); - sb.append(alg); - sb.append(" "); - sb.append(digestid); - if (digest != null) { - sb.append(" "); - sb.append(base16.toString(digest)); - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - footprint = st.getUInt16(); - alg = st.getUInt8(); - digestid = st.getUInt8(); - digest = st.getHex(); - } - - /** - * Creates a DS Record from the given data - * - * @param digestid The digest id code. - * @param key The key to digest - */ - public - DSRecord(Name name, int dclass, long ttl, int digestid, DNSKEYRecord key) { - this(name, dclass, ttl, key.getFootprint(), key.getAlgorithm(), digestid, DNSSEC.generateDSDigest(key, digestid)); - } - - /** - * Creates a DS Record from the given data - * - * @param footprint The original KEY record's footprint (keyid). - * @param alg The original key algorithm. - * @param digestid The digest id code. - * @param digest A hash of the original key. - */ - public - DSRecord(Name name, int dclass, long ttl, int footprint, int alg, int digestid, byte[] digest) { - super(name, DnsRecordType.DS, dclass, ttl); - this.footprint = checkU16("footprint", footprint); - this.alg = checkU8("alg", alg); - this.digestid = checkU8("digestid", digestid); - this.digest = digest; - } - - /** - * Returns the key's algorithm. - */ - public - int getAlgorithm() { - return alg; - } - - /** - * Returns the key's Digest ID. - */ - public - int getDigestID() { - return digestid; - } - - /** - * Returns the binary hash of the key. - */ - public - byte[] getDigest() { - return digest; - } - - /** - * Returns the key's footprint. - */ - public - int getFootprint() { - return footprint; - } - -} diff --git a/src/dorkbox/network/dns/records/DnsMessage.java b/src/dorkbox/network/dns/records/DnsMessage.java deleted file mode 100644 index 659e4f34..00000000 --- a/src/dorkbox/network/dns/records/DnsMessage.java +++ /dev/null @@ -1,1016 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.*; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.util.OS; -import io.netty.buffer.ByteBuf; -import io.netty.util.*; - -/** - * A DNS DnsMessage. A message is the basic unit of communication between - * the client and server of a DNS operation. A message consists of a Header - * and 4 message sections. - * - * @author Brian Wellington - * @see Header - * @see DnsSection - */ -@SuppressWarnings({"unused", "WeakerAccess"}) -public -class DnsMessage extends AbstractReferenceCounted implements Cloneable, ReferenceCounted { - - private static final ResourceLeakDetector leakDetector = ResourceLeakDetectorFactory.instance().newResourceLeakDetector(DnsMessage.class); - private final ResourceLeakTracker leak = leakDetector.track(this); - - /** - * The maximum length of a message in wire format. - */ - public static final int MAXLENGTH = 65535; - - private Header header; - - // To reduce the memory footprint of a message, - // each of the following fields is a single record or a list of records. - private Object questions; - private Object answers; - private Object authorities; - private Object additionals; - - private int size; - - - private TSIG tsigkey; - private TSIGRecord querytsig; - private int tsigerror; - - int tsigstart; - int tsigState; - int sig0start; - - /* The message was not signed */ - static final int TSIG_UNSIGNED = 0; - - /* The message was signed and verification succeeded */ - static final int TSIG_VERIFIED = 1; - - /* The message was an unsigned message in multiple-message response */ - static final int TSIG_INTERMEDIATE = 2; - - /* The message was signed and no verification was attempted. */ - static final int TSIG_SIGNED = 3; - - /* - * The message was signed and verification failed, or was not signed - * when it should have been. - */ - static final int TSIG_FAILED = 4; - - - private static DnsRecord[] emptyRecordArray = new DnsRecord[0]; - private static RRset[] emptyRRsetArray = new RRset[0]; - - /** - * Creates a new DnsMessage with the specified DnsMessage ID - */ - public - DnsMessage(int id) { - this(new Header(id)); - } - - private - DnsMessage(Header header) { - this.header = header; - } - - /** - * Creates a new DnsMessage with a random DnsMessage ID - */ - public - DnsMessage() { - this(new Header()); - } - - /** - * Creates a new DnsMessage with a random DnsMessage ID suitable for sending as a - * query. - * - * @param r A record containing the question - */ - public static - DnsMessage newQuery(DnsRecord r) { - DnsMessage m = new DnsMessage(); - m.header.setOpcode(DnsOpCode.QUERY); - m.header.setFlag(Flags.RD); - m.addRecord(r, DnsSection.QUESTION); - return m; - } - - /** - * Creates a new DnsMessage to contain a dynamic update. A random DnsMessage ID - * and the zone are filled in. - * - * @param zone The zone to be updated - */ - public static - DnsMessage newUpdate(Name zone) { - return new Update(zone); - } - - - - - - - - - /** - * Creates a new DnsMessage from its DNS wire format representation - * - * @param b A byte array containing the DNS DnsMessage. - */ - public - DnsMessage(byte[] b) throws IOException { - this(new DnsInput(b)); - } - - /** - * Creates a new DnsMessage from its DNS wire format representation - * - * @param in A DnsInput containing the DNS DnsMessage. - */ - public - DnsMessage(DnsInput in) throws IOException { - this(new Header(in)); - boolean isUpdate = (header.getOpcode() == DnsOpCode.UPDATE); - boolean truncated = header.getFlag(Flags.TC); - try { - for (int i = 0; i < DnsSection.TOTAL_SECTION_COUNT; i++) { - int count = header.getCount(i); - List records; - - if (count > 0) { - records = newRecordList(count); - setSection(i, records); - - - for (int j = 0; j < count; j++) { - int pos = in.readIndex(); - DnsRecord record = DnsRecord.fromWire(in, i, isUpdate); - - records.add(record); - - if (i == DnsSection.ADDITIONAL) { - if (record.getType() == DnsRecordType.TSIG) { - tsigstart = pos; - } - if (record.getType() == DnsRecordType.SIG) { - SIGRecord sig = (SIGRecord) record; - if (sig.getTypeCovered() == 0) { - sig0start = pos; - } - } - } - } - } - } - } catch (WireParseException e) { - if (!truncated) { - throw e; - } - } - size = in.readIndex(); - } - - /** - * Creates a new DnsMessage from its DNS wire format representation - * - * @param byteBuffer A ByteBuf containing the DNS DnsMessage. - */ - public - DnsMessage(ByteBuf byteBuffer) throws IOException { - this(new DnsInput(byteBuffer)); - } - - @SuppressWarnings("unchecked") - private static - T castRecord(Object record) { - return (T) record; - } - - private static - ArrayList newRecordList(int count) { - return new ArrayList(count); - } - - private static - ArrayList newRecordList() { - return new ArrayList(2); - } - - private - Object sectionAt(int section) { - switch (section) { - case DnsSection.QUESTION: - return questions; - case DnsSection.ANSWER: - return answers; - case DnsSection.AUTHORITY: - return authorities; - case DnsSection.ADDITIONAL: - return additionals; - } - - throw new IndexOutOfBoundsException(); // Should never reach here. - } - - private - void setSection(int section, Object value) { - switch (section) { - case DnsSection.QUESTION: - questions = value; - return; - case DnsSection.ANSWER: - answers = value; - return; - case DnsSection.AUTHORITY: - authorities = value; - return; - case DnsSection.ADDITIONAL: - additionals = value; - return; - } - - throw new IndexOutOfBoundsException(); // Should never reach here. - } - - - /** - * Retrieves the Header. - * - * @see Header - */ - public - Header getHeader() { - return header; - } - - /** - * Replaces the Header with a new one. - * - * @see Header - */ - public - void setHeader(Header h) { - header = h; - } - - /** - * Adds a record to a section of the DnsMessage, and adjusts the header. - * - * @see DnsRecord - * @see DnsSection - */ - public - void addRecord(DnsRecord record, int section) { - final Object records = sectionAt(section); - header.incCount(section); - - if (records == null) { - // it holds no records, so add a single record... - setSection(section, record); - return; - } - - if (records instanceof DnsRecord) { - // it holds a single record, so convert it to multiple records - final List recordList = newRecordList(); - recordList.add(castRecord(records)); - recordList.add(record); - setSection(section, recordList); - return; - } - - // holds a list of records - @SuppressWarnings("unchecked") - final List recordList = (List) records; - recordList.add(record); - } - - /** - * Removes a record from a section of the DnsMessage, and adjusts the header. - * - * @see DnsRecord - * @see DnsSection - */ - public - boolean removeRecord(DnsRecord record, int section) { - final Object records = sectionAt(section); - if (records == null) { - // can't remove a record if there are none - return false; - } - - if (records instanceof DnsRecord) { - setSection(section, null); - header.decCount(section); - return true; - } - - @SuppressWarnings("unchecked") - final List recordList = (List) records; - boolean remove = recordList.remove(record); - - if (remove) { - header.decCount(section); - return true; - } - - return false; - } - - /** - * Removes all records from a section of the DnsMessage, and adjusts the header. - * - * @see DnsRecord - * @see DnsSection - */ - public - void removeAllRecords(int section) { - setSection(section, null); - header.setCount(section, 0); - } - - /** - * Determines if the given record is already present in the given section. - * - * @see DnsRecord - * @see DnsSection - */ - public - boolean findRecord(DnsRecord record, int section) { - final Object records = sectionAt(section); - if (records == null) { - return false; - } - - if (records instanceof DnsRecord) { - return records.equals(record); - } - - @SuppressWarnings("unchecked") - final List recordList = (List) records; - return recordList.contains(record); - } - - /** - * Determines if the given record is already present in any section. - * - * @see DnsRecord - * @see DnsSection - */ - public - boolean findRecord(DnsRecord record) { - for (int i = DnsSection.ANSWER; i <= DnsSection.ADDITIONAL; i++) { - if (findRecord(record, i)) { - return true; - } - } - - return false; - } - - /** - * Determines if an RRset with the given name and type is already - * present in any section. - * - * @see RRset - * @see DnsSection - */ - public - boolean findRRset(Name name, int type) { - return (findRRset(name, type, DnsSection.ANSWER) || findRRset(name, type, DnsSection.AUTHORITY) || findRRset(name, - type, - DnsSection.ADDITIONAL)); - } - - /** - * Determines if an RRset with the given name and type is already - * present in the given section. - * - * @see RRset - * @see DnsSection - */ - public - boolean findRRset(Name name, int type, int section) { - final Object records = sectionAt(section); - if (records == null) { - return false; - } - - - if (records instanceof DnsRecord) { - DnsRecord record = (DnsRecord) records; - return record.getType() == type && name.equals(record.getName()); - } - - - @SuppressWarnings("unchecked") - final List recordList = (List) records; - for (int i = 0; i < recordList.size(); i++) { - final DnsRecord record = recordList.get(i); - - if (record.getType() == type && name.equals(record.getName())) { - return true; - } - } - - return false; - } - - /** - * Returns the first record in the QUESTION section. - * - * @see DnsRecord - * @see DnsSection - */ - public - DnsRecord getQuestion() { - final Object records = sectionAt(DnsSection.QUESTION); - if (records == null) { - return null; - } - - if (records instanceof DnsRecord) { - return (DnsRecord) records; - } - - @SuppressWarnings("unchecked") - final List recordList = (List) records; - return recordList.get(0); - } - - /** - * Returns the TSIG record from the ADDITIONAL section, if one is present. - * - * @see TSIGRecord - * @see TSIG - * @see DnsSection - */ - public - TSIGRecord getTSIG() { - final Object records = sectionAt(DnsSection.ADDITIONAL); - if (records == null) { - return null; - } - - if (records instanceof DnsRecord) { - DnsRecord record = (DnsRecord) records; - if (record.type != DnsRecordType.TSIG) { - return null; - } else { - return (TSIGRecord) record; - } - } - - @SuppressWarnings("unchecked") - final List recordList = (List) records; - - DnsRecord record = recordList.get(recordList.size() - 1); - if (record.type != DnsRecordType.TSIG) { - return null; - } - else { - return (TSIGRecord) record; - } - } - - /** - * Returns an array containing all records in the given section grouped into - * RRsets. - * - * @see RRset - * @see DnsSection - */ - public - RRset[] getSectionRRsets(int section) { - final Object records = sectionAt(section); - if (records == null) { - return emptyRRsetArray; - } - - List sets = new ArrayList(header.getCount(section)); - Set hash = new HashSet(); - - - if (records instanceof DnsRecord) { - DnsRecord record = (DnsRecord) records; - - // only 1, so no need to make it complicated - return new RRset[] {new RRset(record)}; - } - - - // now there are multiple records - @SuppressWarnings("unchecked") - final List recordList = (List) records; - - for (int i = 0; i < recordList.size(); i++) { - final DnsRecord record = recordList.get(i); - - Name name = record.getName(); - boolean newset = true; - - if (hash.contains(name)) { - for (int j = sets.size() - 1; j >= 0; j--) { - RRset set = sets.get(j); - - if (set.getType() == record.getRRsetType() && - set.getDClass() == record.getDClass() && - set.getName().equals(name)) { - - set.addRR(record); - newset = false; - break; - } - } - } - - if (newset) { - RRset set = new RRset(record); - sets.add(set); - hash.add(name); - } - } - - return sets.toArray(new RRset[sets.size()]); - } - - /** - * Returns an array containing all records in the given section, or an - * empty array if the section is empty. - * - * @see DnsRecord - * @see DnsSection - */ - public - DnsRecord[] getSectionArray(int section) { - final Object records = sectionAt(section); - if (records == null) { - return emptyRecordArray; - } - - if (records instanceof DnsRecord) { - DnsRecord record = (DnsRecord) records; - - // only 1, so no need to make it complicated - return new DnsRecord[] {record}; - } - - @SuppressWarnings("unchecked") - final List recordList = (List) records; - return recordList.toArray(new DnsRecord[recordList.size()]); - } - - /** - * Returns an array containing the wire format representation of the DnsMessage. - */ - public - byte[] toWire() { - DnsOutput out = new DnsOutput(); - toWire(out); - size = out.current(); - return out.toByteArray(); - } - - public - void toWire(DnsOutput out) { - header.toWire(out); - Compression c = new Compression(); - for (int i = 0; i < DnsSection.TOTAL_SECTION_COUNT; i++) { - final Object records = sectionAt(i); - if (records == null) { - continue; - } - - if (records instanceof DnsRecord) { - DnsRecord record = (DnsRecord) records; - record.toWire(out, i, c); - continue; - } - - @SuppressWarnings("unchecked") - final List recordList = (List) records; - for (int j = 0; j < recordList.size(); j++) { - DnsRecord record = recordList.get(j); - record.toWire(out, i, c); - } - } - } - - /** - * Returns an array containing the wire format representation of the DnsMessage - * with the specified maximum length. This will generate a truncated - * message (with the TC bit) if the message doesn't fit, and will also - * sign the message with the TSIG key set by a call to setTSIG(). This - * method may return null if the message could not be rendered at all; this - * could happen if maxLength is smaller than a DNS header, for example. - * - * @param maxLength The maximum length of the message. - * - * @return The wire format of the message, or null if the message could not be - * rendered into the specified length. - * - * @see Flags - * @see TSIG - */ - public - byte[] toWire(int maxLength) { - DnsOutput out = new DnsOutput(); - // this will also prep the output stream. - boolean b = toWire(out, maxLength); - if (!b) { - System.err.println("ERROR CREATING MESSAGE FROM WIRE!"); - } - size = out.current(); - - // we output from the start. - out.getByteBuf().readerIndex(0); - return out.toByteArray(); - } - - /** Returns true if the message could be rendered. */ - private - boolean toWire(DnsOutput out, int maxLength) { - if (maxLength < Header.LENGTH) { - return false; - } - - Header newheader = null; - - int tempMaxLength = maxLength; - if (tsigkey != null) { - tempMaxLength -= tsigkey.recordLength(); - } - - OPTRecord opt = getOPT(); - byte[] optBytes = null; - if (opt != null) { - optBytes = opt.toWire(DnsSection.ADDITIONAL); - tempMaxLength -= optBytes.length; - } - - int startpos = out.current(); - header.toWire(out); - - Compression c = new Compression(); - int flags = header.getFlagsByte(); - int additionalCount = 0; - - for (int i = 0; i < DnsSection.TOTAL_SECTION_COUNT; i++) { - int skipped; - - final Object records = sectionAt(i); - if (records == null) { - continue; - } - - skipped = sectionToWire(out, i, c, tempMaxLength); - if (skipped != 0 && i != DnsSection.ADDITIONAL) { - flags = Header.setFlag(flags, Flags.TC, true); - out.writeU16At(header.getCount(i) - skipped, startpos + 4 + 2 * i); - for (int j = i + 1; j < DnsSection.ADDITIONAL; j++) { - out.writeU16At(0, startpos + 4 + 2 * j); - } - break; - } - if (i == DnsSection.ADDITIONAL) { - additionalCount = header.getCount(i) - skipped; - } - } - - if (optBytes != null) { - out.writeByteArray(optBytes); - additionalCount++; - } - - if (flags != header.getFlagsByte()) { - out.writeU16At(flags, startpos + 2); - } - - if (additionalCount != header.getCount(DnsSection.ADDITIONAL)) { - out.writeU16At(additionalCount, startpos + 10); - } - - if (tsigkey != null) { - TSIGRecord tsigrec = tsigkey.generate(this, out.toByteArray(), tsigerror, querytsig); - - tsigrec.toWire(out, DnsSection.ADDITIONAL, c); - // write size/position info - out.writeU16At(additionalCount + 1, startpos + 10); - } - - return true; - } - - /** - * Returns the OPT record from the ADDITIONAL section, if one is present. - * - * @see OPTRecord - * @see DnsSection - */ - public - OPTRecord getOPT() { - DnsRecord[] additional = getSectionArray(DnsSection.ADDITIONAL); - for (int i = 0; i < additional.length; i++) { - if (additional[i] instanceof OPTRecord) { - return (OPTRecord) additional[i]; - } - } - return null; - } - - /** Returns the number of records not successfully rendered. */ - private - int sectionToWire(DnsOutput out, int section, Compression c, int maxLength) { - final Object records = sectionAt(section); - // will never be null, we check earlier - - int pos = out.current(); - int rendered = 0; - int skipped = 0; - DnsRecord lastRecord = null; - - - - if (records instanceof DnsRecord) { - DnsRecord record = (DnsRecord) records; - - if (section == DnsSection.ADDITIONAL && record.type == DnsRecordType.OPT) { - skipped++; - return skipped; - } - - record.toWire(out, section, c); - - if (out.current() > maxLength) { - out.jump(pos); - return 1 - rendered + skipped; - } - - return skipped; - } - - @SuppressWarnings("unchecked") - final List recordList = (List) records; - int n = recordList.size(); - - for (int i = 0; i < n; i++) { - DnsRecord record = recordList.get(i); - if (section == DnsSection.ADDITIONAL && record.type == DnsRecordType.OPT) { - skipped++; - continue; - } - - if (lastRecord != null && !sameSet(record, lastRecord)) { - pos = out.current(); - rendered = i; - } - - lastRecord = record; - record.toWire(out, section, c); - - if (out.current() > maxLength) { - out.jump(pos); - return n - rendered + skipped; - } - } - return skipped; - } - - private static - boolean sameSet(DnsRecord r1, DnsRecord r2) { - return (r1.getRRsetType() == r2.getRRsetType() && r1.getDClass() == r2.getDClass() && r1.getName() - .equals(r2.getName())); - } - - /** - * Sets the TSIG key and other necessary information to sign a message. - * - * @param key The TSIG key. - * @param error The value of the TSIG error field. - * @param querytsig If this is a response, the TSIG from the request. - */ - public - void setTSIG(TSIG key, int error, TSIGRecord querytsig) { - this.tsigkey = key; - this.tsigerror = error; - this.querytsig = querytsig; - } - - /** - * Creates a SHALLOW copy of this DnsMessage. This is done by the Resolver before adding - * TSIG and OPT records, for example. - * - * @see TSIGRecord - * @see OPTRecord - */ - @Override - public - Object clone() { - DnsMessage m = new DnsMessage(); - - for (int i = 0; i < DnsSection.TOTAL_SECTION_COUNT; i++) { - final Object records = sectionAt(i); - if (records == null) { - continue; - } - - if (records instanceof DnsRecord) { - setSection(i, records); - continue; - } - - @SuppressWarnings("unchecked") - final List recordList = (List) records; - setSection(i, new ArrayList(recordList)); - } - - m.header = (Header) header.clone(); - m.size = size; - return m; - } - - /** - * Converts the DnsMessage to a String. - */ - @Override - public - String toString() { - String NL = OS.LINE_SEPARATOR; - - StringBuilder sb = new StringBuilder(NL); - OPTRecord opt = getOPT(); - - if (opt != null) { - sb.append(header.toStringWithRcode(getRcode())) - .append(NL); - } - else { - sb.append(header) - .append(NL); - } - - if (isSigned()) { - sb.append(";; TSIG "); - if (isVerified()) { - sb.append("ok"); - } - else { - sb.append("invalid"); - } - sb.append(NL); - } - - for (int i = 0; i < 4; i++) { - if (header.getOpcode() != DnsOpCode.UPDATE) { - sb.append(";; ") - .append(DnsSection.longString(i)) - .append(":") - .append(NL); - } - else { - sb.append(";; ") - .append(DnsSection.updString(i)) - .append(":") - .append(NL); - } - sb.append(sectionToString(i)) - .append(NL); - } - - sb.append(";; DnsMessage size: ") - .append(numBytes()) - .append(" bytes"); - return sb.toString(); - } - - /** - * Was this message signed by a TSIG? - * - * @see TSIG - */ - public - boolean isSigned() { - return (tsigState == TSIG_SIGNED || tsigState == TSIG_VERIFIED || tsigState == TSIG_FAILED); - } - - /** - * If this message was signed by a TSIG, was the TSIG verified? - * - * @see TSIG - */ - public - boolean isVerified() { - return (tsigState == TSIG_VERIFIED); - } - - /** - * Returns the message's rcode (error code). This incorporates the EDNS - * extended rcode. - */ - public - int getRcode() { - int rcode = header.getRcode(); - OPTRecord opt = getOPT(); - if (opt != null) { - rcode += (opt.getExtendedRcode() << 4); - } - return rcode; - } - - /** - * Returns the size of the message. Only valid if the message has been converted to or from wire format. - */ - public - int numBytes() { - return size; - } - - /** - * Converts the given section of the DnsMessage to a String. - * - * @see DnsSection - */ - public - String sectionToString(int i) { - if (i > 3) { - return null; - } - - StringBuilder sb = new StringBuilder(); - - DnsRecord[] records = getSectionArray(i); - for (int j = 0; j < records.length; j++) { - DnsRecord rec = records[j]; - if (i == DnsSection.QUESTION) { - sb.append(";;\t") - .append(rec.name); - sb.append(", type = ") - .append(DnsRecordType.string(rec.type)); - sb.append(", class = ") - .append(DnsClass.string(rec.dclass)); - } - else { - sb.append(rec); - } - - sb.append(OS.LINE_SEPARATOR); - } - return sb.toString(); - } - - /** - * Removes all the records in this DNS message. - */ - @SuppressWarnings("unchecked") - public - DnsMessage clear() { - for (int i = 0; i < DnsSection.TOTAL_SECTION_COUNT; i++) { - removeAllRecords(i); - } - return this; - } - - @Override - protected - void deallocate() { - clear(); - - final ResourceLeakTracker leak = this.leak; - if (leak != null) { - boolean closed = leak.close(this); - assert closed; - } - } - - @Override - public - DnsMessage touch(Object hint) { - if (leak != null) { - leak.record(hint); - } - return this; - } -} diff --git a/src/dorkbox/network/dns/records/DnsRecord.java b/src/dorkbox/network/dns/records/DnsRecord.java deleted file mode 100644 index 28fd6e73..00000000 --- a/src/dorkbox/network/dns/records/DnsRecord.java +++ /dev/null @@ -1,825 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.Serializable; -import java.text.DecimalFormat; -import java.util.Arrays; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.exceptions.RelativeNameException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.network.dns.utils.Options; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.network.dns.utils.base16; - -/** - * A generic DNS resource record. The specific record types extend this class. - * A record contains a name, type, class, ttl, and rdata. - * - * @author Brian Wellington - */ - -public abstract -class DnsRecord implements Cloneable, Comparable, Serializable { - - private static final long serialVersionUID = 2694906050116005466L; - - protected Name name; - protected int type, dclass; - protected long ttl; - - private static final DecimalFormat byteFormat = new DecimalFormat(); - - static { - byteFormat.setMinimumIntegerDigits(3); - } - - protected - DnsRecord() {} - - DnsRecord(Name name, int type, int dclass, long ttl) { - if (!name.isAbsolute()) { - throw new RelativeNameException(name); - } - DnsRecordType.check(type); - DnsClass.check(dclass); - TTL.check(ttl); - this.name = name; - this.type = type; - this.dclass = dclass; - this.ttl = ttl; - } - - /** - * Creates a new record, with the given parameters. - * - * @param name The owner name of the record. - * @param type The record's type. - * @param dclass The record's class. - * @param ttl The record's time to live. - * @param data The complete rdata of the record, in uncompressed DNS wire - * format. - */ - public static - DnsRecord newRecord(Name name, int type, int dclass, long ttl, byte[] data) { - return newRecord(name, type, dclass, ttl, data.length, data); - } - - /** - * Creates a new record, with the given parameters. - * - * @param name The owner name of the record. - * @param type The record's type. - * @param dclass The record's class. - * @param ttl The record's time to live. - * @param length The length of the record's data. - * @param data The rdata of the record, in uncompressed DNS wire format. Only - * the first length bytes are used. - */ - public static - DnsRecord newRecord(Name name, int type, int dclass, long ttl, int length, byte[] data) { - if (!name.isAbsolute()) { - throw new RelativeNameException(name); - } - DnsRecordType.check(type); - DnsClass.check(dclass); - TTL.check(ttl); - - DnsInput in; - if (data != null) { - in = new DnsInput(data); - } - else { - in = null; - } - try { - return newRecord(name, type, dclass, ttl, length, in); - } catch (IOException e) { - return null; - } - } - - private static - DnsRecord newRecord(Name name, int type, int dclass, long ttl, int length, DnsInput in) throws IOException { - DnsRecord rec; - rec = getEmptyRecord(name, type, dclass, ttl, in != null); - if (in != null) { - if (in.remaining() < length) { - throw new WireParseException("truncated record"); - } - in.setActive(length); - - rec.rrFromWire(in); - - int remaining = in.remaining(); - in.restoreActive(); - - if (remaining > 0) { - throw new WireParseException("invalid record length"); - } - } - return rec; - } - - private static - DnsRecord getEmptyRecord(Name name, int type, int dclass, long ttl, boolean hasData) { - DnsRecord proto, rec; - - if (hasData) { - proto = DnsRecordType.getProto(type); - if (proto != null) { - rec = proto.getObject(); - } - else { - rec = new UNKRecord(); - } - } - else { - rec = new EmptyRecord(); - } - rec.name = name; - rec.type = type; - rec.dclass = dclass; - rec.ttl = ttl; - return rec; - } - - - - - - /** - * Creates an empty record of the correct type; must be overriden - */ - abstract - DnsRecord getObject(); - - /** - * Converts the type-specific RR to wire format - must be overriden - */ - abstract - void rrFromWire(DnsInput in) throws IOException; - - - - /** - * Creates a new empty record, with the given parameters. - * - * @param name The owner name of the record. - * @param type The record's type. - * @param dclass The record's class. - * @param ttl The record's time to live. - * - * @return An object of a subclass of Record - */ - public static - DnsRecord newRecord(Name name, int type, int dclass, long ttl) { - if (!name.isAbsolute()) { - throw new RelativeNameException(name); - } - DnsRecordType.check(type); - DnsClass.check(dclass); - TTL.check(ttl); - - return getEmptyRecord(name, type, dclass, ttl, false); - } - - /** - * Creates a new empty record, with the given parameters. This method is - * designed to create records that will be added to the QUERY section - * of a message. - * - * @param name The owner name of the record. - * @param type The record's type. - * @param dclass The record's class. - * - * @return An object of a subclass of Record - */ - public static - DnsRecord newRecord(Name name, int type, int dclass) { - return newRecord(name, type, dclass, 0); - } - - static - DnsRecord fromWire(DnsInput in, int section, boolean isUpdate) throws IOException { - int type, dclass; - long ttl; - int length; - Name name; - DnsRecord rec; - - name = new Name(in); - type = in.readU16(); - dclass = in.readU16(); - - if (section == DnsSection.QUESTION) { - return newRecord(name, type, dclass); - } - - ttl = in.readU32(); - length = in.readU16(); - if (length == 0 && isUpdate && (section == DnsSection.PREREQ || section == DnsSection.UPDATE)) { - return newRecord(name, type, dclass, ttl); - } - rec = newRecord(name, type, dclass, ttl, length, in); - return rec; - } - - static - DnsRecord fromWire(DnsInput in, int section) throws IOException { - return fromWire(in, section, false); - } - - /** - * Builds a Record from DNS uncompressed wire format. - */ - public static - DnsRecord fromWire(byte[] b, int section) throws IOException { - return fromWire(new DnsInput(b), section, false); - } - - - - - - - - /** - * Converts a Record into DNS uncompressed wire format. - */ - public - byte[] toWire(int section) { - DnsOutput out = new DnsOutput(); - toWire(out, section, null); - return out.toByteArray(); - } - - void toWire(DnsOutput out, int section, Compression c) { - name.toWire(out, c); - out.writeU16(type); - out.writeU16(dclass); - if (section == DnsSection.QUESTION) { - return; - } - out.writeU32(ttl); - int lengthPosition = out.current(); - out.writeU16(0); /* until we know better */ - rrToWire(out, c, false); - int rrlength = out.current() - lengthPosition - 2; - out.writeU16At(rrlength, lengthPosition); - } - - /** - * Converts the type-specific RR to wire format - must be overriden - */ - abstract - void rrToWire(DnsOutput out, Compression c, boolean canonical); - - /** - * Converts a Record into canonical DNS uncompressed wire format (all names are - * converted to lowercase). - */ - public - byte[] toWireCanonical() { - return toWireCanonical(false); - } - - /* - * Converts a Record into canonical DNS uncompressed wire format (all names are - * converted to lowercase), optionally ignoring the TTL. - */ - private - byte[] toWireCanonical(boolean noTTL) { - DnsOutput out = new DnsOutput(); - toWireCanonical(out, noTTL); - return out.toByteArray(); - } - - private - void toWireCanonical(DnsOutput out, boolean noTTL) { - name.toWireCanonical(out); - out.writeU16(type); - out.writeU16(dclass); - if (noTTL) { - out.writeU32(0); - } - else { - out.writeU32(ttl); - } - int lengthPosition = out.current(); - out.writeU16(0); /* until we know better */ - rrToWire(out, null, true); - int rrlength = out.current() - lengthPosition - 2; - out.writeU16At(rrlength, lengthPosition); - } - - /** - * Converts the rdata portion of a Record into a String representation - */ - public - void rdataToString(StringBuilder sb) { - rrToString(sb); - } - - /** - * Converts the type-specific RR to text format - must be overriden - */ - abstract - void rrToString(StringBuilder sb); - - /** - * Converts the text format of an RR to the internal format - must be overriden - */ - abstract - void rdataFromString(Tokenizer st, Name origin) throws IOException; - - /** - * Converts a String into a byte array. - */ - protected static - byte[] byteArrayFromString(String s) throws TextParseException { - byte[] array = s.getBytes(); - boolean escaped = false; - boolean hasEscapes = false; - - for (int i = 0; i < array.length; i++) { - if (array[i] == '\\') { - hasEscapes = true; - break; - } - } - if (!hasEscapes) { - if (array.length > 255) { - throw new TextParseException("text string too long"); - } - return array; - } - - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - int digits = 0; - int intval = 0; - for (int i = 0; i < array.length; i++) { - byte b = array[i]; - if (escaped) { - if (b >= '0' && b <= '9' && digits < 3) { - digits++; - intval *= 10; - intval += (b - '0'); - if (intval > 255) { - throw new TextParseException("bad escape"); - } - if (digits < 3) { - continue; - } - b = (byte) intval; - } - else if (digits > 0 && digits < 3) { - throw new TextParseException("bad escape"); - } - os.write(b); - escaped = false; - } - else if (array[i] == '\\') { - escaped = true; - digits = 0; - intval = 0; - } - else { - os.write(array[i]); - } - } - if (digits > 0 && digits < 3) { - throw new TextParseException("bad escape"); - } - array = os.toByteArray(); - if (array.length > 255) { - throw new TextParseException("text string too long"); - } - - return os.toByteArray(); - } - - /** - * Converts a byte array into a String. - */ - protected static - String byteArrayToString(byte[] array, boolean quote) { - StringBuilder sb = new StringBuilder(); - if (quote) { - sb.append('"'); - } - for (int i = 0; i < array.length; i++) { - int b = array[i] & 0xFF; - if (b < 0x20 || b >= 0x7f) { - sb.append('\\'); - sb.append(byteFormat.format(b)); - } - else if (b == '"' || b == '\\') { - sb.append('\\'); - sb.append((char) b); - } - else { - sb.append((char) b); - } - } - if (quote) { - sb.append('"'); - } - return sb.toString(); - } - - /** - * Converts a byte array into the unknown RR format. - */ - protected static - String unknownToString(byte[] data) { - StringBuilder sb = new StringBuilder(); - sb.append("\\# "); - sb.append(data.length); - sb.append(" "); - sb.append(base16.toString(data)); - return sb.toString(); - } - - /** - * Builds a new Record from its textual representation - * - * @param name The owner name of the record. - * @param type The record's type. - * @param dclass The record's class. - * @param ttl The record's time to live. - * @param st A tokenizer containing the textual representation of the rdata. - * @param origin The default origin to be appended to relative domain names. - * - * @return The new record - * - * @throws IOException The text format was invalid. - */ - public static - DnsRecord fromString(Name name, int type, int dclass, long ttl, Tokenizer st, Name origin) throws IOException { - DnsRecord rec; - - if (!name.isAbsolute()) { - throw new RelativeNameException(name); - } - DnsRecordType.check(type); - DnsClass.check(dclass); - TTL.check(ttl); - - Tokenizer.Token t = st.get(); - if (t.type == Tokenizer.IDENTIFIER && t.value.equals("\\#")) { - int length = st.getUInt16(); - byte[] data = st.getHex(); - if (data == null) { - data = new byte[0]; - } - if (length != data.length) { - throw st.exception("invalid unknown RR encoding: " + "length mismatch"); - } - DnsInput in = new DnsInput(data); - return newRecord(name, type, dclass, ttl, length, in); - } - st.unget(); - rec = getEmptyRecord(name, type, dclass, ttl, true); - rec.rdataFromString(st, origin); - t = st.get(); - if (t.type != Tokenizer.EOL && t.type != Tokenizer.EOF) { - throw st.exception("unexpected tokens at end of record"); - } - return rec; - } - - /** - * Builds a new Record from its textual representation - * - * @param name The owner name of the record. - * @param type The record's type. - * @param dclass The record's class. - * @param ttl The record's time to live. - * @param s The textual representation of the rdata. - * @param origin The default origin to be appended to relative domain names. - * - * @return The new record - * - * @throws IOException The text format was invalid. - */ - public static - DnsRecord fromString(Name name, int type, int dclass, long ttl, String s, Name origin) throws IOException { - return fromString(name, type, dclass, ttl, new Tokenizer(s), origin); - } - - /** - * Returns the record's name - * - * @see Name - */ - public - Name getName() { - return name; - } - - /** - * Returns the record's type - * - * @see DnsRecordType - */ - public - int getType() { - return type; - } - - /** - * Returns the record's class - */ - public - int getDClass() { - return dclass; - } - - /** - * Returns the record's TTL - */ - public - long getTTL() { - return ttl; - } - - /* Sets the TTL to the specified value. This is intentionally not public. EDIT: public now so we can change it if we want to */ - public - void setTTL(long ttl) { - this.ttl = ttl; - } - - /** - * Determines if two Records could be part of the same RRset. - * This compares the name, type, and class of the Records; the ttl and - * rdata are not compared. - */ - public - boolean sameRRset(DnsRecord rec) { - return (getRRsetType() == rec.getRRsetType() && dclass == rec.dclass && name.equals(rec.name)); - } - - /** - * Returns the type of RRset that this record would belong to. For all types - * except RRSIG, this is equivalent to getType(). - * - * @return The type of record, if not RRSIG. If the type is RRSIG, - * the type covered is returned. - * - * @see DnsRecordType - * @see RRset - * @see SIGRecord - */ - public - int getRRsetType() { - if (type == DnsRecordType.RRSIG) { - RRSIGRecord sig = (RRSIGRecord) this; - return sig.getTypeCovered(); - } - return type; - } - - /** - * Generates a hash code based on the Record's data. - */ - @Override - public - int hashCode() { - byte[] array = toWireCanonical(true); - int code = 0; - for (int i = 0; i < array.length; i++) { - code += ((code << 3) + (array[i] & 0xFF)); - } - return code; - } - - /** - * Determines if two Records are identical. This compares the name, type, - * class, and rdata (with names canonicalized). The TTLs are not compared. - * - * @param arg The record to compare to - * - * @return true if the records are equal, false otherwise. - */ - @Override - public - boolean equals(Object arg) { - if (arg == null || !(arg instanceof DnsRecord)) { - return false; - } - DnsRecord r = (DnsRecord) arg; - if (type != r.type || dclass != r.dclass || !name.equals(r.name)) { - return false; - } - byte[] array1 = rdataToWireCanonical(); - byte[] array2 = r.rdataToWireCanonical(); - return Arrays.equals(array1, array2); - } - - /** - * Converts the rdata in a Record into canonical DNS uncompressed wire format - * (all names are converted to lowercase). - */ - public - byte[] rdataToWireCanonical() { - DnsOutput out = new DnsOutput(); - rrToWire(out, null, true); - return out.toByteArray(); - } - - /** - * Converts a Record into a String representation - */ - @Override - public final - String toString() { - StringBuilder sb = new StringBuilder(); - toString(sb); - return sb.toString(); - } - - /** - * Converts a Record into a String representation in a StringBuilder - */ - public - void toString(StringBuilder sb) { - sb.append(name); - if (sb.length() < 8) { - sb.append("\t"); - } - if (sb.length() < 16) { - sb.append("\t"); - } - sb.append("\t"); - if (Options.check("BINDTTL")) { - sb.append(TTL.format(ttl)); - } - else { - sb.append(ttl); - } - sb.append("\t"); - if (dclass != DnsClass.IN || !Options.check("noPrintIN")) { - sb.append(DnsClass.string(dclass)); - sb.append("\t"); - } - sb.append(DnsRecordType.string(type)); - - sb.append("\t"); - int length = sb.length(); - rrToString(sb); - - if (length == sb.length()) { - // delete the /t since we had no record data - sb.deleteCharAt(length-1); - } - } - - /** - * Creates a new record identical to the current record, but with a different - * name. This is most useful for replacing the name of a wildcard record. - */ - public - DnsRecord withName(Name name) { - if (!name.isAbsolute()) { - throw new RelativeNameException(name); - } - DnsRecord rec = cloneRecord(); - rec.name = name; - return rec; - } - - DnsRecord cloneRecord() { - try { - return (DnsRecord) clone(); - } catch (CloneNotSupportedException e) { - throw new IllegalStateException(); - } - } - - /** - * Creates a new record identical to the current record, but with a different - * class and ttl. This is most useful for dynamic update. - */ - DnsRecord withDClass(int dclass, long ttl) { - DnsRecord rec = cloneRecord(); - rec.dclass = dclass; - rec.ttl = ttl; - return rec; - } - - /** - * Compares this Record to another Object. - * - * @param o The Object to be compared. - * - * @return The value 0 if the argument is a record equivalent to this record; - * a value less than 0 if the argument is less than this record in the - * canonical ordering, and a value greater than 0 if the argument is greater - * than this record in the canonical ordering. The canonical ordering - * is defined to compare by name, class, type, and rdata. - * - * @throws ClassCastException if the argument is not a Record. - */ - @Override - public - int compareTo(Object o) { - DnsRecord arg = (DnsRecord) o; - - if (this == arg) { - return (0); - } - - int n = name.compareTo(arg.name); - if (n != 0) { - return (n); - } - n = dclass - arg.dclass; - if (n != 0) { - return (n); - } - n = type - arg.type; - if (n != 0) { - return (n); - } - byte[] rdata1 = rdataToWireCanonical(); - byte[] rdata2 = arg.rdataToWireCanonical(); - for (int i = 0; i < rdata1.length && i < rdata2.length; i++) { - n = (rdata1[i] & 0xFF) - (rdata2[i] & 0xFF); - if (n != 0) { - return (n); - } - } - return (rdata1.length - rdata2.length); - } - - /** - * Returns the name for which additional data processing should be done - * for this record. This can be used both for building responses and - * parsing responses. - * - * @return The name to used for additional data processing, or null if this - * record type does not require additional data processing. - */ - public - Name getAdditionalName() { - return null; - } - - /* Checks that an int contains an unsigned 8 bit value */ - static - int checkU8(String field, int val) { - if (val < 0 || val > 0xFF) { - throw new IllegalArgumentException("\"" + field + "\" " + val + " must be an unsigned 8 " + "bit value"); - } - return val; - } - - /* Checks that an int contains an unsigned 16 bit value */ - static - int checkU16(String field, int val) { - if (val < 0 || val > 0xFFFF) { - throw new IllegalArgumentException("\"" + field + "\" " + val + " must be an unsigned 16 " + "bit value"); - } - return val; - } - - /* Checks that a long contains an unsigned 32 bit value */ - static - long checkU32(String field, long val) { - if (val < 0 || val > 0xFFFFFFFFL) { - throw new IllegalArgumentException("\"" + field + "\" " + val + " must be an unsigned 32 " + "bit value"); - } - return val; - } - - /* Checks that a name is absolute */ - static - Name checkName(String field, Name name) { - if (!name.isAbsolute()) { - throw new RelativeNameException(name); - } - return name; - } - - static - byte[] checkByteArrayLength(String field, byte[] array, int maxLength) { - if (array.length > 0xFFFF) { - throw new IllegalArgumentException("\"" + field + "\" array " + "must have no more than " + maxLength + " elements"); - } - byte[] out = new byte[array.length]; - System.arraycopy(array, 0, out, 0, array.length); - return out; - } -} diff --git a/src/dorkbox/network/dns/records/DnsTypeProtoAssignment.java b/src/dorkbox/network/dns/records/DnsTypeProtoAssignment.java deleted file mode 100644 index 23658792..00000000 --- a/src/dorkbox/network/dns/records/DnsTypeProtoAssignment.java +++ /dev/null @@ -1,78 +0,0 @@ -package dorkbox.network.dns.records; - -import dorkbox.network.dns.constants.DnsRecordType; - -public -class DnsTypeProtoAssignment { - - // this is so we don't have to make each type constructor public - public static - void assign(final DnsRecordType.TypeMnemonic types) { - types.add(DnsRecordType.A, "A", new ARecord()); - types.add(DnsRecordType.NS, "NS", new NSRecord()); - types.add(DnsRecordType.MD, "MD", new MDRecord()); - types.add(DnsRecordType.MF, "MF", new MFRecord()); - types.add(DnsRecordType.CNAME, "CNAME", new CNAMERecord()); - types.add(DnsRecordType.SOA, "SOA", new SOARecord()); - types.add(DnsRecordType.MB, "MB", new MBRecord()); - types.add(DnsRecordType.MG, "MG", new MGRecord()); - types.add(DnsRecordType.MR, "MR", new MRRecord()); - types.add(DnsRecordType.NULL, "NULL", new NULLRecord()); - types.add(DnsRecordType.WKS, "WKS", new WKSRecord()); - types.add(DnsRecordType.PTR, "PTR", new PTRRecord()); - types.add(DnsRecordType.HINFO, "HINFO", new HINFORecord()); - types.add(DnsRecordType.MINFO, "MINFO", new MINFORecord()); - types.add(DnsRecordType.MX, "MX", new MXRecord()); - types.add(DnsRecordType.TXT, "TXT", new TXTRecord()); - types.add(DnsRecordType.RP, "RP", new RPRecord()); - types.add(DnsRecordType.AFSDB, "AFSDB", new AFSDBRecord()); - types.add(DnsRecordType.X25, "X25", new X25Record()); - types.add(DnsRecordType.ISDN, "ISDN", new ISDNRecord()); - types.add(DnsRecordType.RT, "RT", new RTRecord()); - types.add(DnsRecordType.NSAP, "NSAP", new NSAPRecord()); - types.add(DnsRecordType.NSAP_PTR, "NSAP-PTR", new NSAP_PTRRecord()); - types.add(DnsRecordType.SIG, "SIG", new SIGRecord()); - types.add(DnsRecordType.KEY, "KEY", new KEYRecord()); - types.add(DnsRecordType.PX, "PX", new PXRecord()); - types.add(DnsRecordType.GPOS, "GPOS", new GPOSRecord()); - types.add(DnsRecordType.AAAA, "AAAA", new AAAARecord()); - types.add(DnsRecordType.LOC, "LOC", new LOCRecord()); - types.add(DnsRecordType.NXT, "NXT", new NXTRecord()); - types.add(DnsRecordType.EID, "EID"); - types.add(DnsRecordType.NIMLOC, "NIMLOC"); - types.add(DnsRecordType.SRV, "SRV", new SRVRecord()); - types.add(DnsRecordType.ATMA, "ATMA"); - types.add(DnsRecordType.NAPTR, "NAPTR", new NAPTRRecord()); - types.add(DnsRecordType.KX, "KX", new KXRecord()); - types.add(DnsRecordType.CERT, "CERT", new CERTRecord()); - types.add(DnsRecordType.A6, "A6", new A6Record()); - types.add(DnsRecordType.DNAME, "DNAME", new DNAMERecord()); - types.add(DnsRecordType.OPT, "OPT", new OPTRecord()); - types.add(DnsRecordType.APL, "APL", new APLRecord()); - types.add(DnsRecordType.DS, "DS", new DSRecord()); - types.add(DnsRecordType.SSHFP, "SSHFP", new SSHFPRecord()); - types.add(DnsRecordType.IPSECKEY, "IPSECKEY", new IPSECKEYRecord()); - types.add(DnsRecordType.RRSIG, "RRSIG", new RRSIGRecord()); - types.add(DnsRecordType.NSEC, "NSEC", new NSECRecord()); - types.add(DnsRecordType.DNSKEY, "DNSKEY", new DNSKEYRecord()); - types.add(DnsRecordType.DHCID, "DHCID", new DHCIDRecord()); - types.add(DnsRecordType.NSEC3, "NSEC3", new NSEC3Record()); - types.add(DnsRecordType.NSEC3PARAM, "NSEC3PARAM", new NSEC3PARAMRecord()); - types.add(DnsRecordType.TLSA, "TLSA", new TLSARecord()); - types.add(DnsRecordType.SMIMEA, "SMIMEA", new SMIMEARecord()); - types.add(DnsRecordType.SMIMEA, "HIP"); - types.add(DnsRecordType.OPENPGPKEY, "OPENPGPKEY", new OPENPGPKEYRecord()); - types.add(DnsRecordType.SPF, "SPF", new SPFRecord()); - types.add(DnsRecordType.TKEY, "TKEY", new TKEYRecord()); - types.add(DnsRecordType.TSIG, "TSIG", new TSIGRecord()); - types.add(DnsRecordType.IXFR, "IXFR"); - types.add(DnsRecordType.AXFR, "AXFR"); - types.add(DnsRecordType.MAILB, "MAILB"); - types.add(DnsRecordType.MAILA, "MAILA"); - types.add(DnsRecordType.ANY, "ANY"); - types.add(DnsRecordType.URI, "URI", new URIRecord()); - types.add(DnsRecordType.CAA, "CAA", new CAARecord()); - types.add(DnsRecordType.TA, "TA"); - types.add(DnsRecordType.DLV, "DLV", new DLVRecord()); - } -} diff --git a/src/dorkbox/network/dns/records/EDNSOption.java b/src/dorkbox/network/dns/records/EDNSOption.java deleted file mode 100644 index c9f1ff6a..00000000 --- a/src/dorkbox/network/dns/records/EDNSOption.java +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.util.Arrays; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Mnemonic; -import dorkbox.network.dns.exceptions.WireParseException; - -/** - * DNS extension options, as described in RFC 2671. The rdata of an OPT record - * is defined as a list of options; this represents a single option. - * - * @author Brian Wellington - * @author Ming Zhou <mizhou@bnivideo.com>, Beaumaris Networks - */ -public abstract -class EDNSOption { - - private final int code; - - - public static - class Code { - /** - * Name Server Identifier, RFC 5001 - */ - public final static int NSID = 3; - /** - * Client Subnet, defined in draft-vandergaast-edns-client-subnet-02 - */ - public final static int CLIENT_SUBNET = 8; - private static Mnemonic codes = new Mnemonic("EDNS Option Codes", Mnemonic.CASE_UPPER); - - private - Code() {} - - static { - codes.setMaximum(0xFFFF); - codes.setPrefix("CODE"); - codes.setNumericAllowed(true); - - codes.add(NSID, "NSID"); - codes.add(CLIENT_SUBNET, "CLIENT_SUBNET"); - } - - /** - * Converts an EDNS Option Code into its textual representation - */ - public static - String string(int code) { - return codes.getText(code); - } - - /** - * Converts a textual representation of an EDNS Option Code into its - * numeric value. - * - * @param s The textual representation of the option code - * - * @return The option code, or -1 on error. - */ - public static - int value(String s) { - return codes.getValue(s); - } - } - - /** - * Creates an option with the given option code and data. - */ - public - EDNSOption(int code) { - this.code = DnsRecord.checkU16("code", code); - } - - /** - * Returns the EDNS Option's code. - * - * @return the option code - */ - public - int getCode() { - return code; - } - - /** - * Converts the wire format of an EDNS Option (including code and length) into - * the type-specific format. - * - * @return The option, in wire format. - */ - public static - EDNSOption fromWire(byte[] b) throws IOException { - return fromWire(new DnsInput(b)); - } - - /** - * Converts the wire format of an EDNS Option (including code and length) into - * the type-specific format. - * - * @param in The input stream. - */ - static - EDNSOption fromWire(DnsInput in) throws IOException { - int code, length; - - code = in.readU16(); - length = in.readU16(); - if (in.remaining() < length) { - throw new WireParseException("truncated option"); - } - in.setActive(length); - EDNSOption option; - switch (code) { - case Code.NSID: - option = new NSIDOption(); - break; - case Code.CLIENT_SUBNET: - option = new ClientSubnetOption(); - break; - default: - option = new GenericEDNSOption(code); - break; - } - option.optionFromWire(in); - in.restoreActive(); - - return option; - } - - /** - * Converts the wire format of an EDNS Option (the option data only) into the - * type-specific format. - * - * @param in The input Stream. - */ - abstract - void optionFromWire(DnsInput in) throws IOException; - - /** - * Converts an EDNS Option (including code and length) into wire format. - * - * @return The option, in wire format. - */ - public - byte[] toWire() throws IOException { - DnsOutput out = new DnsOutput(); - toWire(out); - return out.toByteArray(); - } - - /** - * Converts an EDNS Option (including code and length) into wire format. - * - * @param out The output stream. - */ - void toWire(DnsOutput out) { - out.writeU16(code); - int lengthPosition = out.current(); - out.writeU16(0); /* until we know better */ - optionToWire(out); - int length = out.current() - lengthPosition - 2; - out.writeU16At(length, lengthPosition); - } - - /** - * Converts an EDNS Option (the type-specific option data only) into wire format. - * - * @param out The output stream. - */ - abstract - void optionToWire(DnsOutput out); - - /** - * Generates a hash code based on the EDNS Option's data. - */ - public - int hashCode() { - byte[] array = getData(); - int hashval = 0; - for (int i = 0; i < array.length; i++) { - hashval += ((hashval << 3) + (array[i] & 0xFF)); - } - return hashval; - } - - /** - * Determines if two EDNS Options are identical. - * - * @param arg The option to compare to - * - * @return true if the options are equal, false otherwise. - */ - public - boolean equals(Object arg) { - if (arg == null || !(arg instanceof EDNSOption)) { - return false; - } - EDNSOption opt = (EDNSOption) arg; - if (code != opt.code) { - return false; - } - return Arrays.equals(getData(), opt.getData()); - } - - public - String toString() { - StringBuilder sb = new StringBuilder(); - - sb.append("{"); - sb.append(EDNSOption.Code.string(code)); - sb.append(": "); - sb.append(optionToString()); - sb.append("}"); - - return sb.toString(); - } - - abstract - String optionToString(); - - /** - * Returns the EDNS Option's data, as a byte array. - * - * @return the option data - */ - byte[] getData() { - DnsOutput out = new DnsOutput(); - optionToWire(out); - return out.toByteArray(); - } - -} diff --git a/src/dorkbox/network/dns/records/EmptyRecord.java b/src/dorkbox/network/dns/records/EmptyRecord.java deleted file mode 100644 index 980e6d86..00000000 --- a/src/dorkbox/network/dns/records/EmptyRecord.java +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * A class implementing Records with no data; that is, records used in - * the question section of messages and meta-records in dynamic update. - * - * @author Brian Wellington - */ - -class EmptyRecord extends DnsRecord { - - private static final long serialVersionUID = 3601852050646429582L; - - EmptyRecord() {} - - @Override - DnsRecord getObject() { - return new EmptyRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - } - - @Override - void rrToString(StringBuilder sb) { - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - } -} diff --git a/src/dorkbox/network/dns/records/GPOSRecord.java b/src/dorkbox/network/dns/records/GPOSRecord.java deleted file mode 100644 index 2f48c44a..00000000 --- a/src/dorkbox/network/dns/records/GPOSRecord.java +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Geographical Location - describes the physical location of a host. - * - * @author Brian Wellington - */ - -public -class GPOSRecord extends DnsRecord { - - private static final long serialVersionUID = -6349714958085750705L; - - private byte[] latitude, longitude, altitude; - - GPOSRecord() {} - - @Override - DnsRecord getObject() { - return new GPOSRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - longitude = in.readCountedString(); - latitude = in.readCountedString(); - altitude = in.readCountedString(); - try { - validate(getLongitude(), getLatitude()); - } catch (IllegalArgumentException e) { - throw new WireParseException(e.getMessage()); - } - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeCountedString(longitude); - out.writeCountedString(latitude); - out.writeCountedString(altitude); - } - - /** - * Convert to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(byteArrayToString(longitude, true)); - sb.append(" "); - sb.append(byteArrayToString(latitude, true)); - sb.append(" "); - sb.append(byteArrayToString(altitude, true)); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - try { - longitude = byteArrayFromString(st.getString()); - latitude = byteArrayFromString(st.getString()); - altitude = byteArrayFromString(st.getString()); - } catch (TextParseException e) { - throw st.exception(e.getMessage()); - } - try { - validate(getLongitude(), getLatitude()); - } catch (IllegalArgumentException e) { - throw new WireParseException(e.getMessage()); - } - } - - /** - * Creates an GPOS Record from the given data - * - * @param longitude The longitude component of the location. - * @param latitude The latitude component of the location. - * @param altitude The altitude component of the location (in meters above sea - * level). - */ - public - GPOSRecord(Name name, int dclass, long ttl, double longitude, double latitude, double altitude) { - super(name, DnsRecordType.GPOS, dclass, ttl); - validate(longitude, latitude); - this.longitude = Double.toString(longitude) - .getBytes(); - this.latitude = Double.toString(latitude) - .getBytes(); - this.altitude = Double.toString(altitude) - .getBytes(); - } - - private - void validate(double longitude, double latitude) throws IllegalArgumentException { - if (longitude < -90.0 || longitude > 90.0) { - throw new IllegalArgumentException("illegal longitude " + longitude); - } - if (latitude < -180.0 || latitude > 180.0) { - throw new IllegalArgumentException("illegal latitude " + latitude); - } - } - - /** - * Creates an GPOS Record from the given data - * - * @param longitude The longitude component of the location. - * @param latitude The latitude component of the location. - * @param altitude The altitude component of the location (in meters above sea - * level). - */ - public - GPOSRecord(Name name, int dclass, long ttl, String longitude, String latitude, String altitude) { - super(name, DnsRecordType.GPOS, dclass, ttl); - try { - this.longitude = byteArrayFromString(longitude); - this.latitude = byteArrayFromString(latitude); - validate(getLongitude(), getLatitude()); - this.altitude = byteArrayFromString(altitude); - } catch (TextParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } - } - - /** - * Returns the longitude as a double - * - * @throws NumberFormatException The string does not contain a valid numeric - * value. - */ - public - double getLongitude() { - return Double.parseDouble(getLongitudeString()); - } - - /** - * Returns the longitude as a string - */ - public - String getLongitudeString() { - return byteArrayToString(longitude, false); - } - - /** - * Returns the latitude as a double - * - * @throws NumberFormatException The string does not contain a valid numeric - * value. - */ - public - double getLatitude() { - return Double.parseDouble(getLatitudeString()); - } - - /** - * Returns the latitude as a string - */ - public - String getLatitudeString() { - return byteArrayToString(latitude, false); - } - - /** - * Returns the altitude as a double - * - * @throws NumberFormatException The string does not contain a valid numeric - * value. - */ - public - double getAltitude() { - return Double.parseDouble(getAltitudeString()); - } - - /** - * Returns the altitude as a string - */ - public - String getAltitudeString() { - return byteArrayToString(altitude, false); - } - -} diff --git a/src/dorkbox/network/dns/records/GenericEDNSOption.java b/src/dorkbox/network/dns/records/GenericEDNSOption.java deleted file mode 100644 index 8ef64e39..00000000 --- a/src/dorkbox/network/dns/records/GenericEDNSOption.java +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.utils.base16; - -/** - * An EDNSOption with no internal structure. - * - * @author Ming Zhou <mizhou@bnivideo.com>, Beaumaris Networks - * @author Brian Wellington - */ -public -class GenericEDNSOption extends EDNSOption { - - private byte[] data; - - GenericEDNSOption(int code) { - super(code); - } - - /** - * Construct a generic EDNS option. - * - * @param data The contents of the option. - */ - public - GenericEDNSOption(int code, byte[] data) { - super(code); - this.data = DnsRecord.checkByteArrayLength("option data", data, 0xFFFF); - } - - @Override - void optionFromWire(DnsInput in) throws IOException { - data = in.readByteArray(); - } - - @Override - void optionToWire(DnsOutput out) { - out.writeByteArray(data); - } - - @Override - String optionToString() { - return "<" + base16.toString(data) + ">"; - } - -} diff --git a/src/dorkbox/network/dns/records/HINFORecord.java b/src/dorkbox/network/dns/records/HINFORecord.java deleted file mode 100644 index 77dd4423..00000000 --- a/src/dorkbox/network/dns/records/HINFORecord.java +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Host Information - describes the CPU and OS of a host - * - * @author Brian Wellington - */ - -public -class HINFORecord extends DnsRecord { - - private static final long serialVersionUID = -4732870630947452112L; - - private byte[] cpu, os; - - HINFORecord() {} - - @Override - DnsRecord getObject() { - return new HINFORecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - cpu = in.readCountedString(); - os = in.readCountedString(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeCountedString(cpu); - out.writeCountedString(os); - } - - /** - * Converts to a string - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(byteArrayToString(cpu, true)); - sb.append(" "); - sb.append(byteArrayToString(os, true)); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - try { - cpu = byteArrayFromString(st.getString()); - os = byteArrayFromString(st.getString()); - } catch (TextParseException e) { - throw st.exception(e.getMessage()); - } - } - - /** - * Creates an HINFO Record from the given data - * - * @param cpu A string describing the host's CPU - * @param os A string describing the host's OS - * - * @throws IllegalArgumentException One of the strings has invalid escapes - */ - public - HINFORecord(Name name, int dclass, long ttl, String cpu, String os) { - super(name, DnsRecordType.HINFO, dclass, ttl); - try { - this.cpu = byteArrayFromString(cpu); - this.os = byteArrayFromString(os); - } catch (TextParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } - } - - /** - * Returns the host's CPU - */ - public - String getCPU() { - return byteArrayToString(cpu, false); - } - - /** - * Returns the host's OS - */ - public - String getOS() { - return byteArrayToString(os, false); - } - -} diff --git a/src/dorkbox/network/dns/records/Header.java b/src/dorkbox/network/dns/records/Header.java deleted file mode 100644 index 3ff02dd9..00000000 --- a/src/dorkbox/network/dns/records/Header.java +++ /dev/null @@ -1,361 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.constants.DnsOpCode; -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.constants.Flags; -import dorkbox.util.FastThreadLocal; -import dorkbox.util.MersenneTwisterFast; -import dorkbox.util.OS; - -/** - * A DNS message header - * - * @author Brian Wellington - * @see DnsMessage - */ - -public -class Header implements Cloneable { - - private int id; - private int flags; - private int[] counts; - - private static final - FastThreadLocal random = new FastThreadLocal() { - @Override - public - MersenneTwisterFast initialValue() { - return new MersenneTwisterFast(); - } - }; - - - /** - * The length of a DNS Header in wire format. - */ - public static final int LENGTH = 12; - - /** - * Create a new empty header with a random message id - */ - public - Header() { - init(); - } - - private - void init() { - counts = new int[4]; - flags = 0; - id = -1; - } - - /** - * Creates a new Header from its DNS wire format representation - * - * @param b A byte array containing the DNS Header. - */ - public - Header(byte[] b) throws IOException { - this(new DnsInput(b)); - } - - /** - * Parses a Header from a stream containing DNS wire format. - */ - Header(DnsInput in) throws IOException { - this(in.readU16()); - flags = in.readU16(); - for (int i = 0; i < counts.length; i++) { - counts[i] = in.readU16(); - } - } - - /** - * Create a new empty header. - * - * @param id The message id - */ - public - Header(int id) { - init(); - setID(id); - } - - public - byte[] toWire() { - DnsOutput out = new DnsOutput(); - toWire(out); - return out.toByteArray(); - } - - void toWire(DnsOutput out) { - out.writeU16(getID()); - out.writeU16(flags); - for (int i = 0; i < counts.length; i++) { - out.writeU16(counts[i]); - } - } - - /** - * Retrieves the message ID - */ - public - int getID() { - if (id >= 0) { - return id; - } - synchronized (this) { - if (id < 0) { - id = random.get().nextInt(0xffff); - } - return id; - } - } - - /** - * Sets the message ID - */ - public - void setID(int id) { - if (id < 0 || id > 0xffff) { - throw new IllegalArgumentException("DNS message ID " + id + " is out of range"); - } - this.id = id; - } - - /** - * Sets a flag to the supplied value - * - * @see Flags - */ - public - void setFlag(Flags flag) { - checkFlag(flag); - flags = setFlag(flags, flag, true); - } - - static private - void checkFlag(int flag) { - if (!Flags.isFlag(flag)) { - throw new IllegalArgumentException("invalid flag bit " + flag); - } - } - - static private - void checkFlag(Flags flag) { - if (!validFlag(flag)) { - throw new IllegalArgumentException("invalid flag bit " + flag); - } - } - - static private - boolean validFlag(Flags flag) { - return flag != null && (flag.value() >= 0 && flag.value() <= 0xF && Flags.isFlag(flag.value())); - } - - static - int setFlag(int flags, Flags flag, boolean value) { - checkFlag(flag); - - // bits are indexed from left to right - if (value) { - return flags |= (1 << (15 - flag.value())); - } - else { - return flags &= ~(1 << (15 - flag.value())); - } - } - - /** - * Sets a flag to the supplied value - * - * @see Flags - */ - public - void unsetFlag(Flags flag) { - checkFlag(flag); - flags = setFlag(flags, flag, false); - } - - boolean[] getFlags() { - boolean[] array = new boolean[16]; - for (int i = 0; i < array.length; i++) { - if (Flags.isFlag(i)) { - array[i] = getFlag(i); - } - } - return array; - } - - /** - * Retrieves a flag - * - * @see Flags - */ - public - boolean getFlag(Flags flag) { - // bit s are indexed from left to right - return (flags & (1 << (15 - flag.value()))) != 0; - } - - /** - * Retrieves a flag. - * - * @param flagValue ALWAYS checked before using, so additional checks are not necessary - * @see Flags - */ - private - boolean getFlag(int flagValue) { - // bits are indexed from left to right - return (flags & (1 << (15 - flagValue))) != 0; - } - - void setCount(int field, int value) { - if (value < 0 || value > 0xFFFF) { - throw new IllegalArgumentException("DNS section count " + value + " is out of range"); - } - counts[field] = value; - } - - void incCount(int field) { - if (counts[field] == 0xFFFF) { - throw new IllegalStateException("DNS section count cannot " + "be incremented"); - } - counts[field]++; - } - - void decCount(int field) { - if (counts[field] == 0) { - throw new IllegalStateException("DNS section count cannot " + "be decremented"); - } - counts[field]--; - } - - int getFlagsByte() { - return flags; - } - - /* Creates a new Header identical to the current one */ - @Override - public - Object clone() { - Header h = new Header(); - h.id = id; - h.flags = flags; - System.arraycopy(counts, 0, h.counts, 0, counts.length); - return h; - } - - /** - * Converts the header into a String - */ - @Override - public - String toString() { - return toStringWithRcode(getRcode()); - } - - /** - * Retrieves the message's rcode - * - * @see DnsResponseCode - */ - public - int getRcode() { - return flags & 0xF; - } - - /** - * Sets the message's rcode - * - * @see DnsResponseCode - */ - public - void setRcode(int value) { - if (value < 0 || value > 0xF) { - throw new IllegalArgumentException("DNS DnsResponseCode " + value + " is out of range"); - } - flags &= ~0xF; - flags |= value; - } - - String toStringWithRcode(int newrcode) { - StringBuilder sb = new StringBuilder(); - - sb.append(";; ->>HEADER<<- "); - sb.append("opcode: " + DnsOpCode.string(getOpcode())); - sb.append(", status: " + DnsResponseCode.string(newrcode)); - sb.append(", id: " + getID()); - sb.append(OS.LINE_SEPARATOR); - - sb.append(";; flags: ") - .append(printFlags()); - sb.append("; "); - for (int i = 0; i < 4; i++) { - sb.append(DnsSection.string(i)) - .append(": ") - .append(getCount(i)) - .append(" "); - } - return sb.toString(); - } - - /** - * Retrieves the mesasge's opcode - * - * @see DnsOpCode - */ - public - int getOpcode() { - return (flags >> 11) & 0xF; - } - - /** - * Sets the message's opcode - * - * @see DnsOpCode - */ - public - void setOpcode(int value) { - if (value < 0 || value > 0xF) { - throw new IllegalArgumentException("DNS DnsOpCode " + value + "is out of range"); - } - flags &= 0x87FF; - flags |= (value << 11); - } - - /** - * Retrieves the record count for the given section - * - * @see DnsSection - */ - public - int getCount(int field) { - return counts[field]; - } - - /** - * Converts the header's flags into a String - */ - String printFlags() { - StringBuilder sb = new StringBuilder(); - - for (int i = 0; i < 16; i++) { - if (Flags.isFlag(i) && getFlag(i)) { - Flags flag = Flags.toFlag(i); - sb.append(flag.string()); - sb.append(" "); - } - } - return sb.toString(); - } -} diff --git a/src/dorkbox/network/dns/records/IPSECKEYRecord.java b/src/dorkbox/network/dns/records/IPSECKEYRecord.java deleted file mode 100644 index 028acdb4..00000000 --- a/src/dorkbox/network/dns/records/IPSECKEYRecord.java +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.Inet6Address; -import java.net.InetAddress; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.network.dns.utils.Address; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.util.Base64Fast; - -/** - * IPsec Keying Material (RFC 4025) - * - * @author Brian Wellington - */ - -public -class IPSECKEYRecord extends DnsRecord { - - private static final long serialVersionUID = 3050449702765909687L; - private int precedence; - private int gatewayType; - private int algorithmType; - private Object gateway; - private byte[] key; - - - public static - class Algorithm { - public static final int DSA = 1; - public static final int RSA = 2; - private - Algorithm() {} - } - - - public static - class Gateway { - public static final int None = 0; - public static final int IPv4 = 1; - public static final int IPv6 = 2; - public static final int Name = 3; - private - Gateway() {} - } - - IPSECKEYRecord() {} - - @Override - DnsRecord getObject() { - return new IPSECKEYRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - precedence = in.readU8(); - gatewayType = in.readU8(); - algorithmType = in.readU8(); - switch (gatewayType) { - case Gateway.None: - gateway = null; - break; - case Gateway.IPv4: - gateway = InetAddress.getByAddress(in.readByteArray(4)); - break; - case Gateway.IPv6: - gateway = InetAddress.getByAddress(in.readByteArray(16)); - break; - case Gateway.Name: - gateway = new Name(in); - break; - default: - throw new WireParseException("invalid gateway type"); - } - if (in.remaining() > 0) { - key = in.readByteArray(); - } - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU8(precedence); - out.writeU8(gatewayType); - out.writeU8(algorithmType); - switch (gatewayType) { - case Gateway.None: - break; - case Gateway.IPv4: - case Gateway.IPv6: - InetAddress gatewayAddr = (InetAddress) gateway; - out.writeByteArray(gatewayAddr.getAddress()); - break; - case Gateway.Name: - Name gatewayName = (Name) gateway; - gatewayName.toWire(out, null, canonical); - break; - } - if (key != null) { - out.writeByteArray(key); - } - } - - @Override - void rrToString(StringBuilder sb) { - sb.append(precedence); - sb.append(" "); - sb.append(gatewayType); - sb.append(" "); - sb.append(algorithmType); - sb.append(" "); - - switch (gatewayType) { - case Gateway.None: - sb.append("."); - break; - case Gateway.IPv4: - case Gateway.IPv6: - InetAddress gatewayAddr = (InetAddress) gateway; - sb.append(gatewayAddr.getHostAddress()); - break; - case Gateway.Name: - sb.append(gateway); - break; - } - - if (key != null) { - sb.append(" "); - sb.append(Base64Fast.encode2(key)); - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - precedence = st.getUInt8(); - gatewayType = st.getUInt8(); - algorithmType = st.getUInt8(); - switch (gatewayType) { - case Gateway.None: - String s = st.getString(); - if (!s.equals(".")) { - throw new TextParseException("invalid gateway format"); - } - gateway = null; - break; - case Gateway.IPv4: - gateway = st.getAddress(Address.IPv4); - break; - case Gateway.IPv6: - gateway = st.getAddress(Address.IPv6); - break; - case Gateway.Name: - gateway = st.getName(origin); - break; - default: - throw new WireParseException("invalid gateway type"); - } - key = st.getBase64(false); - } - - /** - * Creates an IPSECKEY Record from the given data. - * - * @param precedence The record's precedence. - * @param gatewayType The record's gateway type. - * @param algorithmType The record's algorithm type. - * @param gateway The record's gateway. - * @param key The record's public key. - */ - public - IPSECKEYRecord(Name name, int dclass, long ttl, int precedence, int gatewayType, int algorithmType, Object gateway, byte[] key) { - super(name, DnsRecordType.IPSECKEY, dclass, ttl); - this.precedence = checkU8("precedence", precedence); - this.gatewayType = checkU8("gatewayType", gatewayType); - this.algorithmType = checkU8("algorithmType", algorithmType); - switch (gatewayType) { - case Gateway.None: - this.gateway = null; - break; - case Gateway.IPv4: - if (!(gateway instanceof InetAddress)) { - throw new IllegalArgumentException("\"gateway\" " + "must be an IPv4 " + "address"); - } - this.gateway = gateway; - break; - case Gateway.IPv6: - if (!(gateway instanceof Inet6Address)) { - throw new IllegalArgumentException("\"gateway\" " + "must be an IPv6 " + "address"); - } - this.gateway = gateway; - break; - case Gateway.Name: - if (!(gateway instanceof Name)) { - throw new IllegalArgumentException("\"gateway\" " + "must be a DNS " + "name"); - } - this.gateway = checkName("gateway", (Name) gateway); - break; - default: - throw new IllegalArgumentException("\"gatewayType\" " + "must be between 0 and 3"); - } - - this.key = key; - } - - /** - * Returns the record's precedence. - */ - public - int getPrecedence() { - return precedence; - } - - /** - * Returns the record's gateway type. - */ - public - int getGatewayType() { - return gatewayType; - } - - /** - * Returns the record's algorithm type. - */ - public - int getAlgorithmType() { - return algorithmType; - } - - /** - * Returns the record's gateway. - */ - public - Object getGateway() { - return gateway; - } - - /** - * Returns the record's public key - */ - public - byte[] getKey() { - return key; - } - -} diff --git a/src/dorkbox/network/dns/records/ISDNRecord.java b/src/dorkbox/network/dns/records/ISDNRecord.java deleted file mode 100644 index 9b03e7aa..00000000 --- a/src/dorkbox/network/dns/records/ISDNRecord.java +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * ISDN - identifies the ISDN number and subaddress associated with a name. - * - * @author Brian Wellington - */ - -public -class ISDNRecord extends DnsRecord { - - private static final long serialVersionUID = -8730801385178968798L; - - private byte[] address; - private byte[] subAddress; - - ISDNRecord() {} - - @Override - DnsRecord getObject() { - return new ISDNRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - address = in.readCountedString(); - if (in.remaining() > 0) { - subAddress = in.readCountedString(); - } - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeCountedString(address); - if (subAddress != null) { - out.writeCountedString(subAddress); - } - } - - @Override - void rrToString(StringBuilder sb) { - sb.append(byteArrayToString(address, true)); - - if (subAddress != null) { - sb.append(" "); - sb.append(byteArrayToString(subAddress, true)); - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - try { - address = byteArrayFromString(st.getString()); - Tokenizer.Token t = st.get(); - if (t.isString()) { - subAddress = byteArrayFromString(t.value); - } - else { - st.unget(); - } - } catch (TextParseException e) { - throw st.exception(e.getMessage()); - } - } - - /** - * Creates an ISDN Record from the given data - * - * @param address The ISDN number associated with the domain. - * @param subAddress The subaddress, if any. - * - * @throws IllegalArgumentException One of the strings is invalid. - */ - public - ISDNRecord(Name name, int dclass, long ttl, String address, String subAddress) { - super(name, DnsRecordType.ISDN, dclass, ttl); - try { - this.address = byteArrayFromString(address); - if (subAddress != null) { - this.subAddress = byteArrayFromString(subAddress); - } - } catch (TextParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } - } - - /** - * Returns the ISDN number associated with the domain. - */ - public - String getAddress() { - return byteArrayToString(address, false); - } - - /** - * Returns the ISDN subaddress, or null if there is none. - */ - public - String getSubAddress() { - if (subAddress == null) { - return null; - } - return byteArrayToString(subAddress, false); - } - -} diff --git a/src/dorkbox/network/dns/records/KEYBase.java b/src/dorkbox/network/dns/records/KEYBase.java deleted file mode 100644 index cab88dc6..00000000 --- a/src/dorkbox/network/dns/records/KEYBase.java +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.security.PublicKey; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.utils.Options; -import dorkbox.util.Base64Fast; -import dorkbox.util.OS; - -/** - * The base class for KEY/DNSKEY records, which have identical formats - * - * @author Brian Wellington - */ - -abstract -class KEYBase extends DnsRecord { - - private static final long serialVersionUID = 3469321722693285454L; - - protected int flags, proto, alg; - protected byte[] key; - protected int footprint = -1; - protected PublicKey publicKey = null; - - protected - KEYBase() {} - - public - KEYBase(Name name, int type, int dclass, long ttl, int flags, int proto, int alg, byte[] key) { - super(name, type, dclass, ttl); - this.flags = checkU16("flags", flags); - this.proto = checkU8("proto", proto); - this.alg = checkU8("alg", alg); - this.key = key; - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - flags = in.readU16(); - proto = in.readU8(); - alg = in.readU8(); - if (in.remaining() > 0) { - key = in.readByteArray(); - } - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU16(flags); - out.writeU8(proto); - out.writeU8(alg); - if (key != null) { - out.writeByteArray(key); - } - } - - /** - * Converts the DNSKEY/KEY Record to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(flags); - sb.append(" "); - sb.append(proto); - sb.append(" "); - sb.append(alg); - - if (key != null) { - if (Options.check("multiline")) { - sb.append(" (") - .append(OS.LINE_SEPARATOR); - - sb.append(Base64Fast.formatString(Base64Fast.encode2(key), 64, "\t", true)); - sb.append(" ; key_tag = "); - sb.append(getFootprint()); - } - else { - sb.append(" "); - sb.append(Base64Fast.encode2(key)); - } - } - } - - /** - * Returns the key's footprint (after computing it) - */ - public - int getFootprint() { - if (footprint >= 0) { - return footprint; - } - - int foot = 0; - - DnsOutput out = new DnsOutput(); - rrToWire(out, null, false); - byte[] rdata = out.toByteArray(); - - if (alg == DNSSEC.Algorithm.RSAMD5) { - int d1 = rdata[rdata.length - 3] & 0xFF; - int d2 = rdata[rdata.length - 2] & 0xFF; - foot = (d1 << 8) + d2; - } - else { - int i; - for (i = 0; i < rdata.length - 1; i += 2) { - int d1 = rdata[i] & 0xFF; - int d2 = rdata[i + 1] & 0xFF; - foot += ((d1 << 8) + d2); - } - if (i < rdata.length) { - int d1 = rdata[i] & 0xFF; - foot += (d1 << 8); - } - foot += ((foot >> 16) & 0xFFFF); - } - footprint = (foot & 0xFFFF); - return footprint; - } - - /** - * Returns the flags describing the key's properties - */ - public - int getFlags() { - return flags; - } - - /** - * Returns the protocol that the key was created for - */ - public - int getProtocol() { - return proto; - } - - /** - * Returns the key's algorithm - */ - public - int getAlgorithm() { - return alg; - } - - /** - * Returns the binary data representing the key - */ - public - byte[] getKey() { - return key; - } - - /** - * Returns a PublicKey corresponding to the data in this key. - * - * @throws DNSSEC.DNSSECException The key could not be converted. - */ - public - PublicKey getPublicKey() throws DNSSEC.DNSSECException { - if (publicKey != null) { - return publicKey; - } - - publicKey = DNSSEC.toPublicKey(this); - return publicKey; - } - -} diff --git a/src/dorkbox/network/dns/records/KEYRecord.java b/src/dorkbox/network/dns/records/KEYRecord.java deleted file mode 100644 index a5ffb561..00000000 --- a/src/dorkbox/network/dns/records/KEYRecord.java +++ /dev/null @@ -1,421 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.security.PublicKey; -import java.util.StringTokenizer; - -import dorkbox.network.dns.Mnemonic; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Key - contains a cryptographic public key. The data can be converted - * to objects implementing java.security.interfaces.PublicKey - * - * @author Brian Wellington - * @see DNSSEC - */ - -public -class KEYRecord extends KEYBase { - - private static final long serialVersionUID = 6385613447571488906L; - /** - * This key cannot be used for confidentiality (encryption) - */ - public static final int FLAG_NOCONF = Flags.NOCONF; - /** - * This key cannot be used for authentication - */ - public static final int FLAG_NOAUTH = Flags.NOAUTH; - -/* flags */ - /** - * This key cannot be used for authentication or confidentiality - */ - public static final int FLAG_NOKEY = Flags.NOKEY; - /** - * A zone key - */ - public static final int OWNER_ZONE = Flags.ZONE; - /** - * A host/end entity key - */ - public static final int OWNER_HOST = Flags.HOST; - /** - * A user key - */ - public static final int OWNER_USER = Flags.USER; - /** - * Key was created for use with transaction level security - */ - public static final int PROTOCOL_TLS = Protocol.TLS; - /** - * Key was created for use with email - */ - public static final int PROTOCOL_EMAIL = Protocol.EMAIL; - -/* protocols */ - /** - * Key was created for use with DNSSEC - */ - public static final int PROTOCOL_DNSSEC = Protocol.DNSSEC; - /** - * Key was created for use with IPSEC - */ - public static final int PROTOCOL_IPSEC = Protocol.IPSEC; - /** - * Key was created for use with any protocol - */ - public static final int PROTOCOL_ANY = Protocol.ANY; - - - public static - class Protocol { - /** - * No defined protocol. - */ - public static final int NONE = 0; - /** - * Transaction Level Security - */ - public static final int TLS = 1; - /** - * Email - */ - public static final int EMAIL = 2; - /** - * DNSSEC - */ - public static final int DNSSEC = 3; - /** - * IPSEC Control - */ - public static final int IPSEC = 4; - /** - * Any protocol - */ - public static final int ANY = 255; - private static Mnemonic protocols = new Mnemonic("KEY protocol", Mnemonic.CASE_UPPER); - - /** - * KEY protocol identifiers. - */ - - private - Protocol() {} - - static { - protocols.setMaximum(0xFF); - protocols.setNumericAllowed(true); - - protocols.add(NONE, "NONE"); - protocols.add(TLS, "TLS"); - protocols.add(EMAIL, "EMAIL"); - protocols.add(DNSSEC, "DNSSEC"); - protocols.add(IPSEC, "IPSEC"); - protocols.add(ANY, "ANY"); - } - - /** - * Converts an KEY protocol value into its textual representation - */ - public static - String string(int type) { - return protocols.getText(type); - } - - /** - * Converts a textual representation of a KEY protocol into its - * numeric code. Integers in the range 0..255 are also accepted. - * - * @param s The textual representation of the protocol - * - * @return The protocol code, or -1 on error. - */ - public static - int value(String s) { - return protocols.getValue(s); - } - } - - - public static - class Flags { - /** - * KEY cannot be used for confidentiality - */ - public static final int NOCONF = 0x4000; - /** - * KEY cannot be used for authentication - */ - public static final int NOAUTH = 0x8000; - /** - * No key present - */ - public static final int NOKEY = 0xC000; - /** - * Bitmask of the use fields - */ - public static final int USE_MASK = 0xC000; - /** - * Flag 2 (unused) - */ - public static final int FLAG2 = 0x2000; - /** - * Flags extension - */ - public static final int EXTEND = 0x1000; - /** - * Flag 4 (unused) - */ - public static final int FLAG4 = 0x0800; - /** - * Flag 5 (unused) - */ - public static final int FLAG5 = 0x0400; - /** - * Key is owned by a user. - */ - public static final int USER = 0x0000; - /** - * Key is owned by a zone. - */ - public static final int ZONE = 0x0100; - /** - * Key is owned by a host. - */ - public static final int HOST = 0x0200; - /** - * Key owner type 3 (reserved). - */ - public static final int NTYP3 = 0x0300; - /** - * Key owner bitmask. - */ - public static final int OWNER_MASK = 0x0300; - /** - * Flag 8 (unused) - */ - public static final int FLAG8 = 0x0080; - /** - * Flag 9 (unused) - */ - public static final int FLAG9 = 0x0040; - /** - * Flag 10 (unused) - */ - public static final int FLAG10 = 0x0020; - /** - * Flag 11 (unused) - */ - public static final int FLAG11 = 0x0010; - /** - * Signatory value 0 - */ - public static final int SIG0 = 0; - /** - * Signatory value 1 - */ - public static final int SIG1 = 1; - /** - * Signatory value 2 - */ - public static final int SIG2 = 2; - /** - * Signatory value 3 - */ - public static final int SIG3 = 3; - /** - * Signatory value 4 - */ - public static final int SIG4 = 4; - /** - * Signatory value 5 - */ - public static final int SIG5 = 5; - /** - * Signatory value 6 - */ - public static final int SIG6 = 6; - /** - * Signatory value 7 - */ - public static final int SIG7 = 7; - /** - * Signatory value 8 - */ - public static final int SIG8 = 8; - /** - * Signatory value 9 - */ - public static final int SIG9 = 9; - /** - * Signatory value 10 - */ - public static final int SIG10 = 10; - /** - * Signatory value 11 - */ - public static final int SIG11 = 11; - /** - * Signatory value 12 - */ - public static final int SIG12 = 12; - /** - * Signatory value 13 - */ - public static final int SIG13 = 13; - /** - * Signatory value 14 - */ - public static final int SIG14 = 14; - /** - * Signatory value 15 - */ - public static final int SIG15 = 15; - private static Mnemonic flags = new Mnemonic("KEY flags", Mnemonic.CASE_UPPER); - - /** - * KEY flags identifiers. - */ - - private - Flags() {} - - static { - flags.setMaximum(0xFFFF); - flags.setNumericAllowed(false); - - flags.add(NOCONF, "NOCONF"); - flags.add(NOAUTH, "NOAUTH"); - flags.add(NOKEY, "NOKEY"); - flags.add(FLAG2, "FLAG2"); - flags.add(EXTEND, "EXTEND"); - flags.add(FLAG4, "FLAG4"); - flags.add(FLAG5, "FLAG5"); - flags.add(USER, "USER"); - flags.add(ZONE, "ZONE"); - flags.add(HOST, "HOST"); - flags.add(NTYP3, "NTYP3"); - flags.add(FLAG8, "FLAG8"); - flags.add(FLAG9, "FLAG9"); - flags.add(FLAG10, "FLAG10"); - flags.add(FLAG11, "FLAG11"); - flags.add(SIG0, "SIG0"); - flags.add(SIG1, "SIG1"); - flags.add(SIG2, "SIG2"); - flags.add(SIG3, "SIG3"); - flags.add(SIG4, "SIG4"); - flags.add(SIG5, "SIG5"); - flags.add(SIG6, "SIG6"); - flags.add(SIG7, "SIG7"); - flags.add(SIG8, "SIG8"); - flags.add(SIG9, "SIG9"); - flags.add(SIG10, "SIG10"); - flags.add(SIG11, "SIG11"); - flags.add(SIG12, "SIG12"); - flags.add(SIG13, "SIG13"); - flags.add(SIG14, "SIG14"); - flags.add(SIG15, "SIG15"); - } - - /** - * Converts a textual representation of KEY flags into its - * numeric code. Integers in the range 0..65535 are also accepted. - * - * @param s The textual representation of the protocol - * - * @return The protocol code, or -1 on error. - */ - public static - int value(String s) { - int value; - try { - value = Integer.parseInt(s); - if (value >= 0 && value <= 0xFFFF) { - return value; - } - return -1; - } catch (NumberFormatException e) { - } - StringTokenizer st = new StringTokenizer(s, "|"); - value = 0; - while (st.hasMoreTokens()) { - int val = flags.getValue(st.nextToken()); - if (val < 0) { - return -1; - } - value |= val; - } - return value; - } - } - - KEYRecord() {} - - @Override - DnsRecord getObject() { - return new KEYRecord(); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - String flagString = st.getIdentifier(); - flags = Flags.value(flagString); - if (flags < 0) { - throw st.exception("Invalid flags: " + flagString); - } - String protoString = st.getIdentifier(); - proto = Protocol.value(protoString); - if (proto < 0) { - throw st.exception("Invalid protocol: " + protoString); - } - String algString = st.getIdentifier(); - alg = DNSSEC.Algorithm.value(algString); - if (alg < 0) { - throw st.exception("Invalid algorithm: " + algString); - } - /* If this is a null KEY, there's no key data */ - if ((flags & Flags.USE_MASK) == Flags.NOKEY) { - key = null; - } - else { - key = st.getBase64(); - } - } - - /** - * Creates a KEY Record from the given data - * - * @param flags Flags describing the key's properties - * @param proto The protocol that the key was created for - * @param alg The key's algorithm - * @param key Binary data representing the key - */ - public - KEYRecord(Name name, int dclass, long ttl, int flags, int proto, int alg, byte[] key) { - super(name, DnsRecordType.KEY, dclass, ttl, flags, proto, alg, key); - } - - /** - * Creates a KEY Record from the given data - * - * @param flags Flags describing the key's properties - * @param proto The protocol that the key was created for - * @param alg The key's algorithm - * @param key The key as a PublicKey - * - * @throws DNSSEC.DNSSECException The PublicKey could not be converted into DNS - * format. - */ - public - KEYRecord(Name name, int dclass, long ttl, int flags, int proto, int alg, PublicKey key) throws DNSSEC.DNSSECException { - super(name, DnsRecordType.KEY, dclass, ttl, flags, proto, alg, DNSSEC.fromPublicKey(key, alg)); - publicKey = key; - } - -} diff --git a/src/dorkbox/network/dns/records/KXRecord.java b/src/dorkbox/network/dns/records/KXRecord.java deleted file mode 100644 index abe7c05b..00000000 --- a/src/dorkbox/network/dns/records/KXRecord.java +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * Key Exchange - delegation of authority - * - * @author Brian Wellington - */ - -public -class KXRecord extends U16NameBase { - - private static final long serialVersionUID = 7448568832769757809L; - - KXRecord() {} - - @Override - DnsRecord getObject() { - return new KXRecord(); - } - - @Override - public - Name getAdditionalName() { - return getNameField(); - } - - /** - * Creates a KX Record from the given data - * - * @param preference The preference of this KX. Records with lower priority - * are preferred. - * @param target The host that authority is delegated to - */ - public - KXRecord(Name name, int dclass, long ttl, int preference, Name target) { - super(name, DnsRecordType.KX, dclass, ttl, preference, "preference", target, "target"); - } - - /** - * Returns the target of the KX record - */ - public - Name getTarget() { - return getNameField(); - } - - /** - * Returns the preference of this KX record - */ - public - int getPreference() { - return getU16Field(); - } - -} diff --git a/src/dorkbox/network/dns/records/LOCRecord.java b/src/dorkbox/network/dns/records/LOCRecord.java deleted file mode 100644 index 9f1e4002..00000000 --- a/src/dorkbox/network/dns/records/LOCRecord.java +++ /dev/null @@ -1,349 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.text.DecimalFormat; -import java.text.NumberFormat; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Location - describes the physical location of hosts, networks, subnets. - * - * @author Brian Wellington - */ - -public -class LOCRecord extends DnsRecord { - - private static final long serialVersionUID = 9058224788126750409L; - - private static NumberFormat w2, w3; - - private long size, hPrecision, vPrecision; - private long latitude, longitude, altitude; - - static { - w2 = new DecimalFormat(); - w2.setMinimumIntegerDigits(2); - - w3 = new DecimalFormat(); - w3.setMinimumIntegerDigits(3); - } - - LOCRecord() {} - - @Override - DnsRecord getObject() { - return new LOCRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - int version; - - version = in.readU8(); - if (version != 0) { - throw new WireParseException("Invalid LOC version"); - } - - size = parseLOCformat(in.readU8()); - hPrecision = parseLOCformat(in.readU8()); - vPrecision = parseLOCformat(in.readU8()); - latitude = in.readU32(); - longitude = in.readU32(); - altitude = in.readU32(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU8(0); /* version */ - out.writeU8(toLOCformat(size)); - out.writeU8(toLOCformat(hPrecision)); - out.writeU8(toLOCformat(vPrecision)); - out.writeU32(latitude); - out.writeU32(longitude); - out.writeU32(altitude); - } - - /** - * Convert to a String - */ - @Override - void rrToString(StringBuilder sb) { - /* Latitude */ - sb.append(positionToString(latitude, 'N', 'S')); - sb.append(" "); - - /* Latitude */ - sb.append(positionToString(longitude, 'E', 'W')); - sb.append(" "); - - /* Altitude */ - renderFixedPoint(sb, w2, altitude - 10000000, 100); - sb.append("m "); - - /* Size */ - renderFixedPoint(sb, w2, size, 100); - sb.append("m "); - - /* Horizontal precision */ - renderFixedPoint(sb, w2, hPrecision, 100); - sb.append("m "); - - /* Vertical precision */ - renderFixedPoint(sb, w2, vPrecision, 100); - sb.append("m"); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - latitude = parsePosition(st, "latitude"); - longitude = parsePosition(st, "longitude"); - altitude = parseDouble(st, "altitude", true, -10000000, 4284967295L, 0) + 10000000; - size = parseDouble(st, "size", false, 0, 9000000000L, 100); - hPrecision = parseDouble(st, "horizontal precision", false, 0, 9000000000L, 1000000); - vPrecision = parseDouble(st, "vertical precision", false, 0, 9000000000L, 1000); - } - - private - long parsePosition(Tokenizer st, String type) throws IOException { - boolean isLatitude = type.equals("latitude"); - int deg = 0, min = 0; - double sec = 0; - long value; - String s; - - deg = st.getUInt16(); - if (deg > 180 || (deg > 90 && isLatitude)) { - throw st.exception("Invalid LOC " + type + " degrees"); - } - - s = st.getString(); - try { - min = Integer.parseInt(s); - if (min < 0 || min > 59) { - throw st.exception("Invalid LOC " + type + " minutes"); - } - s = st.getString(); - sec = parseFixedPoint(s); - if (sec < 0 || sec >= 60) { - throw st.exception("Invalid LOC " + type + " seconds"); - } - s = st.getString(); - } catch (NumberFormatException e) { - } - - if (s.length() != 1) { - throw st.exception("Invalid LOC " + type); - } - - value = (long) (1000 * (sec + 60L * (min + 60L * deg))); - - char c = Character.toUpperCase(s.charAt(0)); - if ((isLatitude && c == 'S') || (!isLatitude && c == 'W')) { - value = -value; - } - else if ((isLatitude && c != 'N') || (!isLatitude && c != 'E')) { - throw st.exception("Invalid LOC " + type); - } - - value += (1L << 31); - - return value; - } - - private - double parseFixedPoint(String s) { - if (s.matches("^-?\\d+$")) { - return Integer.parseInt(s); - } - else if (s.matches("^-?\\d+\\.\\d*$")) { - String[] parts = s.split("\\."); - double value = Integer.parseInt(parts[0]); - double fraction = Integer.parseInt(parts[1]); - if (value < 0) { - fraction *= -1; - } - int digits = parts[1].length(); - return value + (fraction / Math.pow(10, digits)); - } - else { - throw new NumberFormatException(); - } - } - - private - long parseDouble(Tokenizer st, String type, boolean required, long min, long max, long defaultValue) throws IOException { - Tokenizer.Token token = st.get(); - if (token.isEOL()) { - if (required) { - throw st.exception("Invalid LOC " + type); - } - st.unget(); - return defaultValue; - } - String s = token.value; - if (s.length() > 1 && s.charAt(s.length() - 1) == 'm') { - s = s.substring(0, s.length() - 1); - } - try { - long value = (long) (100 * parseFixedPoint(s)); - if (value < min || value > max) { - throw st.exception("Invalid LOC " + type); - } - return value; - } catch (NumberFormatException e) { - throw st.exception("Invalid LOC " + type); - } - } - - private - String positionToString(long value, char pos, char neg) { - StringBuilder sb = new StringBuilder(); - char direction; - - long temp = value - (1L << 31); - if (temp < 0) { - temp = -temp; - direction = neg; - } - else { - direction = pos; - } - - sb.append(temp / (3600 * 1000)); /* degrees */ - temp = temp % (3600 * 1000); - sb.append(" "); - - sb.append(temp / (60 * 1000)); /* minutes */ - temp = temp % (60 * 1000); - sb.append(" "); - - renderFixedPoint(sb, w3, temp, 1000); /* seconds */ - sb.append(" "); - - sb.append(direction); - - return sb.toString(); - } - - private - void renderFixedPoint(StringBuilder sb, NumberFormat formatter, long value, long divisor) { - sb.append(value / divisor); - value %= divisor; - - if (value != 0) { - sb.append("."); - sb.append(formatter.format(value)); - } - } - - private - int toLOCformat(long l) { - byte exp = 0; - while (l > 9) { - exp++; - l /= 10; - } - return (int) ((l << 4) + exp); - } - - private static - long parseLOCformat(int b) throws WireParseException { - long out = b >> 4; - int exp = b & 0xF; - if (out > 9 || exp > 9) { - throw new WireParseException("Invalid LOC Encoding"); - } - while (exp-- > 0) { - out *= 10; - } - return (out); - } - - /** - * Creates an LOC Record from the given data - * - * @param latitude The latitude of the center of the sphere - * @param longitude The longitude of the center of the sphere - * @param altitude The altitude of the center of the sphere, in m - * @param size The diameter of a sphere enclosing the described entity, in m. - * @param hPrecision The horizontal precision of the data, in m. - * @param vPrecision The vertical precision of the data, in m. - */ - public - LOCRecord(Name name, - int dclass, - long ttl, - double latitude, - double longitude, - double altitude, - double size, - double hPrecision, - double vPrecision) { - super(name, DnsRecordType.LOC, dclass, ttl); - this.latitude = (long) (latitude * 3600 * 1000 + (1L << 31)); - this.longitude = (long) (longitude * 3600 * 1000 + (1L << 31)); - this.altitude = (long) ((altitude + 100000) * 100); - this.size = (long) (size * 100); - this.hPrecision = (long) (hPrecision * 100); - this.vPrecision = (long) (vPrecision * 100); - } - - /** - * Returns the latitude - */ - public - double getLatitude() { - return ((double) (latitude - (1L << 31))) / (3600 * 1000); - } - - /** - * Returns the longitude - */ - public - double getLongitude() { - return ((double) (longitude - (1L << 31))) / (3600 * 1000); - } - - /** - * Returns the altitude - */ - public - double getAltitude() { - return ((double) (altitude - 10000000)) / 100; - } - - /** - * Returns the diameter of the enclosing sphere - */ - public - double getSize() { - return ((double) size) / 100; - } - - /** - * Returns the horizontal precision - */ - public - double getHPrecision() { - return ((double) hPrecision) / 100; - } - - /** - * Returns the horizontal precision - */ - public - double getVPrecision() { - return ((double) vPrecision) / 100; - } - -} diff --git a/src/dorkbox/network/dns/records/MBRecord.java b/src/dorkbox/network/dns/records/MBRecord.java deleted file mode 100644 index dd7f19bf..00000000 --- a/src/dorkbox/network/dns/records/MBRecord.java +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * Mailbox Record - specifies a host containing a mailbox. - * - * @author Brian Wellington - */ - -public -class MBRecord extends SingleNameBase { - - private static final long serialVersionUID = 532349543479150419L; - - MBRecord() {} - - @Override - DnsRecord getObject() { - return new MBRecord(); - } - - @Override - public - Name getAdditionalName() { - return getSingleName(); - } - - /** - * Creates a new MB Record with the given data - * - * @param mailbox The host containing the mailbox for the domain. - */ - public - MBRecord(Name name, int dclass, long ttl, Name mailbox) { - super(name, DnsRecordType.MB, dclass, ttl, mailbox, "mailbox"); - } - - /** - * Gets the mailbox for the domain - */ - public - Name getMailbox() { - return getSingleName(); - } - -} diff --git a/src/dorkbox/network/dns/records/MDRecord.java b/src/dorkbox/network/dns/records/MDRecord.java deleted file mode 100644 index 9a256e80..00000000 --- a/src/dorkbox/network/dns/records/MDRecord.java +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * Mail Destination Record - specifies a mail agent which delivers mail - * for a domain (obsolete) - * - * @author Brian Wellington - */ - -public -class MDRecord extends SingleNameBase { - - private static final long serialVersionUID = 5268878603762942202L; - - MDRecord() {} - - @Override - DnsRecord getObject() { - return new MDRecord(); - } - - @Override - public - Name getAdditionalName() { - return getSingleName(); - } - - /** - * Creates a new MD Record with the given data - * - * @param mailAgent The mail agent that delivers mail for the domain. - */ - public - MDRecord(Name name, int dclass, long ttl, Name mailAgent) { - super(name, DnsRecordType.MD, dclass, ttl, mailAgent, "mail agent"); - } - - /** - * Gets the mail agent for the domain - */ - public - Name getMailAgent() { - return getSingleName(); - } - -} diff --git a/src/dorkbox/network/dns/records/MFRecord.java b/src/dorkbox/network/dns/records/MFRecord.java deleted file mode 100644 index 54d98e2e..00000000 --- a/src/dorkbox/network/dns/records/MFRecord.java +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * Mail Forwarder Record - specifies a mail agent which forwards mail - * for a domain (obsolete) - * - * @author Brian Wellington - */ - -public -class MFRecord extends SingleNameBase { - - private static final long serialVersionUID = -6670449036843028169L; - - MFRecord() {} - - @Override - DnsRecord getObject() { - return new MFRecord(); - } - - @Override - public - Name getAdditionalName() { - return getSingleName(); - } - - /** - * Creates a new MF Record with the given data - * - * @param mailAgent The mail agent that forwards mail for the domain. - */ - public - MFRecord(Name name, int dclass, long ttl, Name mailAgent) { - super(name, DnsRecordType.MF, dclass, ttl, mailAgent, "mail agent"); - } - - /** - * Gets the mail agent for the domain - */ - public - Name getMailAgent() { - return getSingleName(); - } - -} diff --git a/src/dorkbox/network/dns/records/MGRecord.java b/src/dorkbox/network/dns/records/MGRecord.java deleted file mode 100644 index f2cc63db..00000000 --- a/src/dorkbox/network/dns/records/MGRecord.java +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * Mail Group Record - specifies a mailbox which is a member of a mail group. - * - * @author Brian Wellington - */ - -public -class MGRecord extends SingleNameBase { - - private static final long serialVersionUID = -3980055550863644582L; - - MGRecord() {} - - @Override - DnsRecord getObject() { - return new MGRecord(); - } - - /** - * Creates a new MG Record with the given data - * - * @param mailbox The mailbox that is a member of the group specified by the - * domain. - */ - public - MGRecord(Name name, int dclass, long ttl, Name mailbox) { - super(name, DnsRecordType.MG, dclass, ttl, mailbox, "mailbox"); - } - - /** - * Gets the mailbox in the mail group specified by the domain - */ - public - Name getMailbox() { - return getSingleName(); - } - -} diff --git a/src/dorkbox/network/dns/records/MINFORecord.java b/src/dorkbox/network/dns/records/MINFORecord.java deleted file mode 100644 index 40e74ada..00000000 --- a/src/dorkbox/network/dns/records/MINFORecord.java +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Mailbox information Record - lists the address responsible for a mailing - * list/mailbox and the address to receive error messages relating to the - * mailing list/mailbox. - * - * @author Brian Wellington - */ - -public -class MINFORecord extends DnsRecord { - - private static final long serialVersionUID = -3962147172340353796L; - - private Name responsibleAddress; - private Name errorAddress; - - MINFORecord() {} - - @Override - DnsRecord getObject() { - return new MINFORecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - responsibleAddress = new Name(in); - errorAddress = new Name(in); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - responsibleAddress.toWire(out, null, canonical); - errorAddress.toWire(out, null, canonical); - } - - /** - * Converts the MINFO Record to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(responsibleAddress); - sb.append(" "); - sb.append(errorAddress); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - responsibleAddress = st.getName(origin); - errorAddress = st.getName(origin); - } - - /** - * Creates an MINFO Record from the given data - * - * @param responsibleAddress The address responsible for the - * mailing list/mailbox. - * @param errorAddress The address to receive error messages relating to the - * mailing list/mailbox. - */ - public - MINFORecord(Name name, int dclass, long ttl, Name responsibleAddress, Name errorAddress) { - super(name, DnsRecordType.MINFO, dclass, ttl); - - this.responsibleAddress = checkName("responsibleAddress", responsibleAddress); - this.errorAddress = checkName("errorAddress", errorAddress); - } - - /** - * Gets the address responsible for the mailing list/mailbox. - */ - public - Name getResponsibleAddress() { - return responsibleAddress; - } - - /** - * Gets the address to receive error messages relating to the mailing - * list/mailbox. - */ - public - Name getErrorAddress() { - return errorAddress; - } - -} diff --git a/src/dorkbox/network/dns/records/MRRecord.java b/src/dorkbox/network/dns/records/MRRecord.java deleted file mode 100644 index 7216248d..00000000 --- a/src/dorkbox/network/dns/records/MRRecord.java +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * Mailbox Rename Record - specifies a rename of a mailbox. - * - * @author Brian Wellington - */ - -public -class MRRecord extends SingleNameBase { - - private static final long serialVersionUID = -5617939094209927533L; - - MRRecord() {} - - @Override - DnsRecord getObject() { - return new MRRecord(); - } - - /** - * Creates a new MR Record with the given data - * - * @param newName The new name of the mailbox specified by the domain. - * domain. - */ - public - MRRecord(Name name, int dclass, long ttl, Name newName) { - super(name, DnsRecordType.MR, dclass, ttl, newName, "new name"); - } - - /** - * Gets the new name of the mailbox specified by the domain - */ - public - Name getNewName() { - return getSingleName(); - } - -} diff --git a/src/dorkbox/network/dns/records/MXRecord.java b/src/dorkbox/network/dns/records/MXRecord.java deleted file mode 100644 index 566fe8dc..00000000 --- a/src/dorkbox/network/dns/records/MXRecord.java +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * Mail Exchange - specifies where mail to a domain is sent - * - * @author Brian Wellington - */ - -public -class MXRecord extends U16NameBase { - - private static final long serialVersionUID = 2914841027584208546L; - - MXRecord() {} - - @Override - DnsRecord getObject() { - return new MXRecord(); - } - - @Override - public - Name getAdditionalName() { - return getNameField(); - } - - /** - * Creates an MX Record from the given data - * - * @param priority The priority of this MX. Records with lower priority - * are preferred. - * @param target The host that mail is sent to - */ - public - MXRecord(Name name, int dclass, long ttl, int priority, Name target) { - super(name, DnsRecordType.MX, dclass, ttl, priority, "priority", target, "target"); - } - - /** - * Returns the target of the MX record - */ - public - Name getTarget() { - return getNameField(); - } - - /** - * Returns the priority of this MX record - */ - public - int getPriority() { - return getU16Field(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU16(u16Field); - nameField.toWire(out, c, canonical); - } - -} diff --git a/src/dorkbox/network/dns/records/NAPTRRecord.java b/src/dorkbox/network/dns/records/NAPTRRecord.java deleted file mode 100644 index 788536e6..00000000 --- a/src/dorkbox/network/dns/records/NAPTRRecord.java +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright (c) 2000-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Name Authority Pointer Record - specifies rewrite rule, that when applied - * to an existing string will produce a new domain. - * - * @author Chuck Santos - */ - -public -class NAPTRRecord extends DnsRecord { - - private static final long serialVersionUID = 5191232392044947002L; - - private int order, preference; - private byte[] flags, service, regexp; - private Name replacement; - - NAPTRRecord() {} - - @Override - DnsRecord getObject() { - return new NAPTRRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - order = in.readU16(); - preference = in.readU16(); - flags = in.readCountedString(); - service = in.readCountedString(); - regexp = in.readCountedString(); - replacement = new Name(in); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU16(order); - out.writeU16(preference); - out.writeCountedString(flags); - out.writeCountedString(service); - out.writeCountedString(regexp); - replacement.toWire(out, null, canonical); - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(order); - sb.append(" "); - sb.append(preference); - sb.append(" "); - sb.append(byteArrayToString(flags, true)); - sb.append(" "); - sb.append(byteArrayToString(service, true)); - sb.append(" "); - sb.append(byteArrayToString(regexp, true)); - sb.append(" "); - sb.append(replacement); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - order = st.getUInt16(); - preference = st.getUInt16(); - try { - flags = byteArrayFromString(st.getString()); - service = byteArrayFromString(st.getString()); - regexp = byteArrayFromString(st.getString()); - } catch (TextParseException e) { - throw st.exception(e.getMessage()); - } - replacement = st.getName(origin); - } - - @Override - public - Name getAdditionalName() { - return replacement; - } - - /** - * Creates an NAPTR Record from the given data - * - * @param order The order of this NAPTR. Records with lower order are - * preferred. - * @param preference The preference, used to select between records at the - * same order. - * @param flags The control aspects of the NAPTRRecord. - * @param service The service or protocol available down the rewrite path. - * @param regexp The regular/substitution expression. - * @param replacement The domain-name to query for the next DNS resource - * record, depending on the value of the flags field. - * - * @throws IllegalArgumentException One of the strings has invalid escapes - */ - public - NAPTRRecord(Name name, int dclass, long ttl, int order, int preference, String flags, String service, String regexp, Name replacement) { - super(name, DnsRecordType.NAPTR, dclass, ttl); - this.order = checkU16("order", order); - this.preference = checkU16("preference", preference); - try { - this.flags = byteArrayFromString(flags); - this.service = byteArrayFromString(service); - this.regexp = byteArrayFromString(regexp); - } catch (TextParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } - this.replacement = checkName("replacement", replacement); - } - - /** - * Returns the order - */ - public - int getOrder() { - return order; - } - - /** - * Returns the preference - */ - public - int getPreference() { - return preference; - } - - /** - * Returns flags - */ - public - String getFlags() { - return byteArrayToString(flags, false); - } - - /** - * Returns service - */ - public - String getService() { - return byteArrayToString(service, false); - } - - /** - * Returns regexp - */ - public - String getRegexp() { - return byteArrayToString(regexp, false); - } - - /** - * Returns the replacement domain-name - */ - public - Name getReplacement() { - return replacement; - } - -} diff --git a/src/dorkbox/network/dns/records/NSAPRecord.java b/src/dorkbox/network/dns/records/NSAPRecord.java deleted file mode 100644 index e0a91766..00000000 --- a/src/dorkbox/network/dns/records/NSAPRecord.java +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.network.dns.utils.base16; - -/** - * NSAP Address Record. - * - * @author Brian Wellington - */ - -public -class NSAPRecord extends DnsRecord { - - private static final long serialVersionUID = -1037209403185658593L; - - private byte[] address; - - NSAPRecord() {} - - @Override - DnsRecord getObject() { - return new NSAPRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - address = in.readByteArray(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeByteArray(address); - } - - @Override - void rrToString(StringBuilder sb) { - sb.append("0x") - .append(base16.toString(address)); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - String addr = st.getString(); - this.address = checkAndConvertAddress(addr); - if (this.address == null) { - throw st.exception("invalid NSAP address " + addr); - } - } - - /** - * Creates an NSAP Record from the given data - * - * @param address The NSAP address. - * - * @throws IllegalArgumentException The address is not a valid NSAP address. - */ - public - NSAPRecord(Name name, int dclass, long ttl, String address) { - super(name, DnsRecordType.NSAP, dclass, ttl); - this.address = checkAndConvertAddress(address); - if (this.address == null) { - throw new IllegalArgumentException("invalid NSAP address " + address); - } - } - - private static - byte[] checkAndConvertAddress(String address) { - if (!address.substring(0, 2) - .equalsIgnoreCase("0x")) { - return null; - } - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - boolean partial = false; - int current = 0; - for (int i = 2; i < address.length(); i++) { - char c = address.charAt(i); - if (c == '.') { - continue; - } - int value = Character.digit(c, 16); - if (value == -1) { - return null; - } - if (partial) { - current += value; - bytes.write(current); - partial = false; - } - else { - current = value << 4; - partial = true; - } - - } - if (partial) { - return null; - } - return bytes.toByteArray(); - } - - /** - * Returns the NSAP address. - */ - public - String getAddress() { - return byteArrayToString(address, false); - } - -} diff --git a/src/dorkbox/network/dns/records/NSAP_PTRRecord.java b/src/dorkbox/network/dns/records/NSAP_PTRRecord.java deleted file mode 100644 index 9c84c312..00000000 --- a/src/dorkbox/network/dns/records/NSAP_PTRRecord.java +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * NSAP Pointer Record - maps a domain name representing an NSAP Address to - * a hostname. - * - * @author Brian Wellington - */ - -public -class NSAP_PTRRecord extends SingleNameBase { - - private static final long serialVersionUID = 2386284746382064904L; - - NSAP_PTRRecord() {} - - @Override - DnsRecord getObject() { - return new NSAP_PTRRecord(); - } - - /** - * Creates a new NSAP_PTR Record with the given data - * - * @param target The name of the host with this address - */ - public - NSAP_PTRRecord(Name name, int dclass, long ttl, Name target) { - super(name, DnsRecordType.NSAP_PTR, dclass, ttl, target, "target"); - } - - /** - * Gets the target of the NSAP_PTR Record - */ - public - Name getTarget() { - return getSingleName(); - } - -} diff --git a/src/dorkbox/network/dns/records/NSEC3PARAMRecord.java b/src/dorkbox/network/dns/records/NSEC3PARAMRecord.java deleted file mode 100644 index d61f8eac..00000000 --- a/src/dorkbox/network/dns/records/NSEC3PARAMRecord.java +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.security.NoSuchAlgorithmException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.network.dns.utils.base16; - -/** - * Next SECure name 3 Parameters - this record contains the parameters (hash - * algorithm, salt, iterations) used for a valid, complete NSEC3 chain present - * in a zone. Zones signed using NSEC3 must include this record at the zone apex - * to inform authoritative servers that NSEC3 is being used with the given - * parameters. - * - * @author Brian Wellington - * @author David Blacka - */ - -public -class NSEC3PARAMRecord extends DnsRecord { - - private static final long serialVersionUID = -8689038598776316533L; - - private int hashAlg; - private int flags; - private int iterations; - private byte salt[]; - - NSEC3PARAMRecord() {} - - @Override - DnsRecord getObject() { - return new NSEC3PARAMRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - hashAlg = in.readU8(); - flags = in.readU8(); - iterations = in.readU16(); - - int salt_length = in.readU8(); - if (salt_length > 0) { - salt = in.readByteArray(salt_length); - } - else { - salt = null; - } - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU8(hashAlg); - out.writeU8(flags); - out.writeU16(iterations); - - if (salt != null) { - out.writeU8(salt.length); - out.writeByteArray(salt); - } - else { - out.writeU8(0); - } - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(hashAlg); - sb.append(' '); - sb.append(flags); - sb.append(' '); - sb.append(iterations); - sb.append(' '); - - if (salt == null) { - sb.append('-'); - } - else { - sb.append(base16.toString(salt)); - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - hashAlg = st.getUInt8(); - flags = st.getUInt8(); - iterations = st.getUInt16(); - - String s = st.getString(); - if (s.equals("-")) { - salt = null; - } - else { - st.unget(); - salt = st.getHexString(); - if (salt.length > 255) { - throw st.exception("salt value too long"); - } - } - } - - /** - * Creates an NSEC3PARAM record from the given data. - * - * @param name The ownername of the NSEC3PARAM record (generally the zone name). - * @param dclass The class. - * @param ttl The TTL. - * @param hashAlg The hash algorithm. - * @param flags The value of the flags field. - * @param iterations The number of hash iterations. - * @param salt The salt to use (may be null). - */ - public - NSEC3PARAMRecord(Name name, int dclass, long ttl, int hashAlg, int flags, int iterations, byte[] salt) { - super(name, DnsRecordType.NSEC3PARAM, dclass, ttl); - this.hashAlg = checkU8("hashAlg", hashAlg); - this.flags = checkU8("flags", flags); - this.iterations = checkU16("iterations", iterations); - - if (salt != null) { - if (salt.length > 255) { - throw new IllegalArgumentException("Invalid salt " + "length"); - } - if (salt.length > 0) { - this.salt = new byte[salt.length]; - System.arraycopy(salt, 0, this.salt, 0, salt.length); - } - } - } - - /** - * Returns the hash algorithm - */ - public - int getHashAlgorithm() { - return hashAlg; - } - - /** - * Returns the flags - */ - public - int getFlags() { - return flags; - } - - /** - * Returns the number of iterations - */ - public - int getIterations() { - return iterations; - } - - /** - * Returns the salt - */ - public - byte[] getSalt() { - return salt; - } - - /** - * Hashes a name with the parameters of this NSEC3PARAM record. - * - * @param name The name to hash - * - * @return The hashed version of the name - * - * @throws NoSuchAlgorithmException The hash algorithm is unknown. - */ - public - byte[] hashName(Name name) throws NoSuchAlgorithmException { - return NSEC3Record.hashName(name, hashAlg, iterations, salt); - } - -} diff --git a/src/dorkbox/network/dns/records/NSEC3Record.java b/src/dorkbox/network/dns/records/NSEC3Record.java deleted file mode 100644 index cb1d0748..00000000 --- a/src/dorkbox/network/dns/records/NSEC3Record.java +++ /dev/null @@ -1,301 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.network.dns.utils.base16; -import dorkbox.network.dns.utils.base32; - -/** - * Next SECure name 3 - this record contains the next hashed name in an - * ordered list of hashed names in the zone, and a set of types for which - * records exist for this name. The presence of this record in a response - * signifies a negative response from a DNSSEC-signed zone. - *

- * This replaces the NSEC and NXT records, when used. - * - * @author Brian Wellington - * @author David Blacka - */ - -public -class NSEC3Record extends DnsRecord { - - public static final int SHA1_DIGEST_ID = Digest.SHA1; - private static final long serialVersionUID = -7123504635968932855L; - private int hashAlg; - private int flags; - private int iterations; - private byte[] salt; - private byte[] next; - private TypeBitmap types; - private static final base32 b32 = new base32(base32.Alphabet.BASE32HEX, false, false); - - - public static - class Flags { - /** - * Unsigned delegation are not included in the NSEC3 chain. - */ - public static final int OPT_OUT = 0x01; - - /** - * NSEC3 flags identifiers. - */ - - private - Flags() {} - } - - - public static - class Digest { - /** - * SHA-1 - */ - public static final int SHA1 = 1; - - private - Digest() {} - } - - NSEC3Record() {} - - @Override - DnsRecord getObject() { - return new NSEC3Record(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - hashAlg = in.readU8(); - flags = in.readU8(); - iterations = in.readU16(); - - int salt_length = in.readU8(); - if (salt_length > 0) { - salt = in.readByteArray(salt_length); - } - else { - salt = null; - } - - int next_length = in.readU8(); - next = in.readByteArray(next_length); - types = new TypeBitmap(in); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU8(hashAlg); - out.writeU8(flags); - out.writeU16(iterations); - - if (salt != null) { - out.writeU8(salt.length); - out.writeByteArray(salt); - } - else { - out.writeU8(0); - } - - out.writeU8(next.length); - out.writeByteArray(next); - types.toWire(out); - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(hashAlg); - sb.append(' '); - sb.append(flags); - sb.append(' '); - sb.append(iterations); - sb.append(' '); - - if (salt == null) { - sb.append('-'); - } - else { - sb.append(base16.toString(salt)); - } - - sb.append(' '); - sb.append(b32.toString(next)); - - if (!types.empty()) { - sb.append(' '); - sb.append(types.toString()); - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - hashAlg = st.getUInt8(); - flags = st.getUInt8(); - iterations = st.getUInt16(); - - String s = st.getString(); - if (s.equals("-")) { - salt = null; - } - else { - st.unget(); - salt = st.getHexString(); - if (salt.length > 255) { - throw st.exception("salt value too long"); - } - } - - next = st.getBase32String(b32); - types = new TypeBitmap(st); - } - - /** - * Creates an NSEC3 record from the given data. - * - * @param name The ownername of the NSEC3 record (base32'd hash plus zonename). - * @param dclass The class. - * @param ttl The TTL. - * @param hashAlg The hash algorithm. - * @param flags The value of the flags field. - * @param iterations The number of hash iterations. - * @param salt The salt to use (may be null). - * @param next The next hash (may not be null). - * @param types The types present at the original ownername. - */ - public - NSEC3Record(Name name, int dclass, long ttl, int hashAlg, int flags, int iterations, byte[] salt, byte[] next, int[] types) { - super(name, DnsRecordType.NSEC3, dclass, ttl); - this.hashAlg = checkU8("hashAlg", hashAlg); - this.flags = checkU8("flags", flags); - this.iterations = checkU16("iterations", iterations); - - if (salt != null) { - if (salt.length > 255) { - throw new IllegalArgumentException("Invalid salt"); - } - if (salt.length > 0) { - this.salt = new byte[salt.length]; - System.arraycopy(salt, 0, this.salt, 0, salt.length); - } - } - - if (next.length > 255) { - throw new IllegalArgumentException("Invalid next hash"); - } - this.next = new byte[next.length]; - System.arraycopy(next, 0, this.next, 0, next.length); - this.types = new TypeBitmap(types); - } - - /** - * Returns the hash algorithm - */ - public - int getHashAlgorithm() { - return hashAlg; - } - - /** - * Returns the flags - */ - public - int getFlags() { - return flags; - } - - /** - * Returns the number of iterations - */ - public - int getIterations() { - return iterations; - } - - /** - * Returns the salt - */ - public - byte[] getSalt() { - return salt; - } - - /** - * Returns the next hash - */ - public - byte[] getNext() { - return next; - } - - /** - * Returns the set of types defined for this name - */ - public - int[] getTypes() { - return types.toArray(); - } - - /** - * Returns whether a specific type is in the set of types. - */ - public - boolean hasType(int type) { - return types.contains(type); - } - - /** - * Hashes a name with the parameters of this NSEC3 record. - * - * @param name The name to hash - * - * @return The hashed version of the name - * - * @throws NoSuchAlgorithmException The hash algorithm is unknown. - */ - public - byte[] hashName(Name name) throws NoSuchAlgorithmException { - return hashName(name, hashAlg, iterations, salt); - } - - static - byte[] hashName(Name name, int hashAlg, int iterations, byte[] salt) throws NoSuchAlgorithmException { - MessageDigest digest; - switch (hashAlg) { - case Digest.SHA1: - digest = MessageDigest.getInstance("sha-1"); - break; - default: - throw new NoSuchAlgorithmException("Unknown NSEC3 algorithm" + "identifier: " + hashAlg); - } - byte[] hash = null; - for (int i = 0; i <= iterations; i++) { - digest.reset(); - if (i == 0) { - digest.update(name.toWireCanonical()); - } - else { - digest.update(hash); - } - if (salt != null) { - digest.update(salt); - } - hash = digest.digest(); - } - return hash; - } - -} diff --git a/src/dorkbox/network/dns/records/NSECRecord.java b/src/dorkbox/network/dns/records/NSECRecord.java deleted file mode 100644 index ddd666bf..00000000 --- a/src/dorkbox/network/dns/records/NSECRecord.java +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Next SECure name - this record contains the following name in an - * ordered list of names in the zone, and a set of types for which - * records exist for this name. The presence of this record in a response - * signifies a negative response from a DNSSEC-signed zone. - *

- * This replaces the NXT record. - * - * @author Brian Wellington - * @author David Blacka - */ - -public -class NSECRecord extends DnsRecord { - - private static final long serialVersionUID = -5165065768816265385L; - - private Name next; - private TypeBitmap types; - - NSECRecord() {} - - @Override - DnsRecord getObject() { - return new NSECRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - next = new Name(in); - types = new TypeBitmap(in); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - // Note: The next name is not lowercased. - next.toWire(out, null, false); - types.toWire(out); - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(next); - - if (!types.empty()) { - sb.append(' '); - sb.append(types.toString()); - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - next = st.getName(origin); - types = new TypeBitmap(st); - } - - /** - * Creates an NSEC Record from the given data. - * - * @param next The following name in an ordered list of the zone - * @param types An array containing the types present. - */ - public - NSECRecord(Name name, int dclass, long ttl, Name next, int[] types) { - super(name, DnsRecordType.NSEC, dclass, ttl); - this.next = checkName("next", next); - for (int i = 0; i < types.length; i++) { - DnsRecordType.check(types[i]); - } - this.types = new TypeBitmap(types); - } - - /** - * Returns the next name - */ - public - Name getNext() { - return next; - } - - /** - * Returns the set of types defined for this name - */ - public - int[] getTypes() { - return types.toArray(); - } - - /** - * Returns whether a specific type is in the set of types. - */ - public - boolean hasType(int type) { - return types.contains(type); - } - -} diff --git a/src/dorkbox/network/dns/records/NSIDOption.java b/src/dorkbox/network/dns/records/NSIDOption.java deleted file mode 100644 index 4304c8ba..00000000 --- a/src/dorkbox/network/dns/records/NSIDOption.java +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -/** - * The Name Server Identifier Option, define in RFC 5001. - * - * @author Brian Wellington - * @see OPTRecord - */ -public -class NSIDOption extends GenericEDNSOption { - - private static final long serialVersionUID = 74739759292589056L; - - NSIDOption() { - super(EDNSOption.Code.NSID); - } - - /** - * Construct an NSID option. - * - * @param data The contents of the option. - */ - public - NSIDOption(byte[] data) { - super(EDNSOption.Code.NSID, data); - } - -} diff --git a/src/dorkbox/network/dns/records/NSRecord.java b/src/dorkbox/network/dns/records/NSRecord.java deleted file mode 100644 index ef522158..00000000 --- a/src/dorkbox/network/dns/records/NSRecord.java +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * Name Server Record - contains the name server serving the named zone - * - * @author Brian Wellington - */ - -public -class NSRecord extends SingleCompressedNameBase { - - private static final long serialVersionUID = 487170758138268838L; - - NSRecord() {} - - @Override - DnsRecord getObject() { - return new NSRecord(); - } - - @Override - public - Name getAdditionalName() { - return getSingleName(); - } - - /** - * Creates a new NS Record with the given data - * - * @param target The name server for the given domain - */ - public - NSRecord(Name name, int dclass, long ttl, Name target) { - super(name, DnsRecordType.NS, dclass, ttl, target, "target"); - } - - /** - * Gets the target of the NS Record - */ - public - Name getTarget() { - return getSingleName(); - } - -} diff --git a/src/dorkbox/network/dns/records/NULLRecord.java b/src/dorkbox/network/dns/records/NULLRecord.java deleted file mode 100644 index cdb48cca..00000000 --- a/src/dorkbox/network/dns/records/NULLRecord.java +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * The NULL Record. This has no defined purpose, but can be used to - * hold arbitrary data. - * - * @author Brian Wellington - */ - -public -class NULLRecord extends DnsRecord { - - private static final long serialVersionUID = -5796493183235216538L; - - private byte[] data; - - NULLRecord() {} - - @Override - DnsRecord getObject() { - return new NULLRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - data = in.readByteArray(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeByteArray(data); - } - - @Override - void rrToString(StringBuilder sb) { - sb.append(unknownToString(data)); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - throw st.exception("no defined text format for NULL records"); - } - - /** - * Creates a NULL record from the given data. - * - * @param data The contents of the record. - */ - public - NULLRecord(Name name, int dclass, long ttl, byte[] data) { - super(name, DnsRecordType.NULL, dclass, ttl); - - if (data.length > 0xFFFF) { - throw new IllegalArgumentException("data must be <65536 bytes"); - } - this.data = data; - } - - /** - * Returns the contents of this record. - */ - public - byte[] getData() { - return data; - } - -} diff --git a/src/dorkbox/network/dns/records/NXTRecord.java b/src/dorkbox/network/dns/records/NXTRecord.java deleted file mode 100644 index 1b385fed..00000000 --- a/src/dorkbox/network/dns/records/NXTRecord.java +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.util.BitSet; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Next name - this record contains the following name in an ordered list - * of names in the zone, and a set of types for which records exist for - * this name. The presence of this record in a response signifies a - * failed query for data in a DNSSEC-signed zone. - * - * @author Brian Wellington - */ - -public -class NXTRecord extends DnsRecord { - - private static final long serialVersionUID = -8851454400765507520L; - - private Name next; - private BitSet bitmap; - - NXTRecord() {} - - @Override - DnsRecord getObject() { - return new NXTRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - next = new Name(in); - bitmap = new BitSet(); - int bitmapLength = in.remaining(); - for (int i = 0; i < bitmapLength; i++) { - int t = in.readU8(); - for (int j = 0; j < 8; j++) { - if ((t & (1 << (7 - j))) != 0) { - bitmap.set(i * 8 + j); - } - } - } - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - next.toWire(out, null, canonical); - int length = bitmap.length(); - for (int i = 0, t = 0; i < length; i++) { - t |= (bitmap.get(i) ? (1 << (7 - i % 8)) : 0); - if (i % 8 == 7 || i == length - 1) { - out.writeU8(t); - t = 0; - } - } - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(next); - int length = bitmap.length(); - for (short i = 0; i < length; i++) { - if (bitmap.get(i)) { - sb.append(" "); - sb.append(DnsRecordType.string(i)); - } - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - next = st.getName(origin); - bitmap = new BitSet(); - while (true) { - Tokenizer.Token t = st.get(); - if (!t.isString()) { - break; - } - int typecode = DnsRecordType.value(t.value, true); - if (typecode <= 0 || typecode > 128) { - throw st.exception("Invalid type: " + t.value); - } - bitmap.set(typecode); - } - st.unget(); - } - - /** - * Creates an NXT Record from the given data - * - * @param next The following name in an ordered list of the zone - * @param bitmap The set of type for which records exist at this name - */ - public - NXTRecord(Name name, int dclass, long ttl, Name next, BitSet bitmap) { - super(name, DnsRecordType.NXT, dclass, ttl); - this.next = checkName("next", next); - this.bitmap = bitmap; - } - - /** - * Returns the next name - */ - public - Name getNext() { - return next; - } - - /** - * Returns the set of types defined for this name - */ - public - BitSet getBitmap() { - return bitmap; - } - -} diff --git a/src/dorkbox/network/dns/records/OPENPGPKEYRecord.java b/src/dorkbox/network/dns/records/OPENPGPKEYRecord.java deleted file mode 100644 index 221d3e90..00000000 --- a/src/dorkbox/network/dns/records/OPENPGPKEYRecord.java +++ /dev/null @@ -1,88 +0,0 @@ -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Options; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.util.Base64Fast; -import dorkbox.util.OS; - -/** - * OPENPGPKEY Record - Stores an OpenPGP certificate associated with a name. - * RFC 7929. - * - * @author Brian Wellington - * @author Valentin Hauner - */ -public -class OPENPGPKEYRecord extends DnsRecord { - - private static final long serialVersionUID = -1277262990243423062L; - - private byte[] cert; - - OPENPGPKEYRecord() {} - - @Override - DnsRecord getObject() { - return new OPENPGPKEYRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - cert = in.readByteArray(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeByteArray(cert); - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - if (cert != null) { - if (Options.check("multiline")) { - sb.append("(") - .append(OS.LINE_SEPARATOR); - sb.append(Base64Fast.formatString(Base64Fast.encode2(cert), 64, "\t", true)); - } - else { - sb.append("\t"); - sb.append(Base64Fast.encode2(cert)); - } - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - cert = st.getBase64(); - } - - /** - * Creates an OPENPGPKEY Record from the given data - * - * @param cert Binary data representing the certificate - */ - public - OPENPGPKEYRecord(Name name, int dclass, long ttl, byte[] cert) { - super(name, DnsRecordType.OPENPGPKEY, dclass, ttl); - this.cert = cert; - } - - /** - * Returns the binary representation of the certificate - */ - public - byte[] getCert() { - return cert; - } - -} diff --git a/src/dorkbox/network/dns/records/OPTRecord.java b/src/dorkbox/network/dns/records/OPTRecord.java deleted file mode 100644 index 2016520d..00000000 --- a/src/dorkbox/network/dns/records/OPTRecord.java +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.constants.ExtendedFlags; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Options - describes Extended DNS (EDNS) properties of a DnsMessage. - * No specific options are defined other than those specified in the - * header. An OPT should be generated by Resolver. - *

- * EDNS is a method to extend the DNS protocol while providing backwards - * compatibility and not significantly changing the protocol. This - * implementation of EDNS is mostly complete at level 0. - * - * @author Brian Wellington - * @see DnsMessage - */ - -public -class OPTRecord extends DnsRecord { - - private static final long serialVersionUID = -6254521894809367938L; - - private List options; - - OPTRecord() {} - - @Override - DnsRecord getObject() { - return new OPTRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - if (in.remaining() > 0) { - options = new ArrayList(); - } - while (in.remaining() > 0) { - EDNSOption option = EDNSOption.fromWire(in); - options.add(option); - } - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - if (options == null) { - return; - } - Iterator it = options.iterator(); - while (it.hasNext()) { - EDNSOption option = (EDNSOption) it.next(); - option.toWire(out); - } - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - if (options != null) { - sb.append(options); - sb.append(" "); - } - - sb.append(" ; payload "); - sb.append(getPayloadSize()); - sb.append(", xrcode "); - sb.append(getExtendedRcode()); - sb.append(", version "); - sb.append(getVersion()); - sb.append(", flags "); - sb.append(getFlags()); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - throw st.exception("no text format defined for OPT"); - } - - /** - * Determines if two OPTRecords are identical. This compares the name, type, - * class, and rdata (with names canonicalized). Additionally, because TTLs - * are relevant for OPT records, the TTLs are compared. - * - * @param arg The record to compare to - * - * @return true if the records are equal, false otherwise. - */ - @Override - public - boolean equals(final Object arg) { - return super.equals(arg) && ttl == ((OPTRecord) arg).ttl; - } - - /** - * Returns the maximum allowed payload size. - */ - public - int getPayloadSize() { - return dclass; - } - - /** - * Returns the extended DnsResponseCode - * - * @see DnsResponseCode - */ - public - int getExtendedRcode() { - return (int) (ttl >>> 24); - } - - /** - * Returns the highest supported EDNS version - */ - public - int getVersion() { - return (int) ((ttl >>> 16) & 0xFF); - } - - /** - * Returns the EDNS flags - */ - public - int getFlags() { - return (int) (ttl & 0xFFFF); - } - - /** - * Creates an OPT Record with no data. This is normally called by - * SimpleResolver, but can also be called by a server. - * - * @param payloadSize The size of a packet that can be reassembled on the - * sending host. - * @param xrcode The value of the extended rcode field. This is the upper - * 16 bits of the full rcode. - * @param flags Additional message flags. - * @param version The EDNS version that this DNS implementation supports. - * This should be 0 for dnsjava. - * - * @see ExtendedFlags - */ - public - OPTRecord(int payloadSize, int xrcode, int version, int flags) { - this(payloadSize, xrcode, version, flags, null); - } - - /** - * Creates an OPT Record. This is normally called by SimpleResolver, but can - * also be called by a server. - * - * @param payloadSize The size of a packet that can be reassembled on the - * sending host. - * @param xrcode The value of the extended rcode field. This is the upper - * 16 bits of the full rcode. - * @param flags Additional message flags. - * @param version The EDNS version that this DNS implementation supports. - * This should be 0 for dnsjava. - * @param options The list of options that comprise the data field. There - * are currently no defined options. - * - * @see ExtendedFlags - */ - public - OPTRecord(int payloadSize, int xrcode, int version, int flags, List options) { - super(Name.root, DnsRecordType.OPT, payloadSize, 0); - checkU16("payloadSize", payloadSize); - checkU8("xrcode", xrcode); - checkU8("version", version); - checkU16("flags", flags); - ttl = ((long) xrcode << 24) + ((long) version << 16) + flags; - if (options != null) { - this.options = new ArrayList(options); - } - } - - /** - * Creates an OPT Record with no data. This is normally called by - * SimpleResolver, but can also be called by a server. - */ - public - OPTRecord(int payloadSize, int xrcode, int version) { - this(payloadSize, xrcode, version, 0, null); - } - - /** - * Gets all options in the OPTRecord. This returns a list of EDNSOptions. - */ - public - List getOptions() { - if (options == null) { - return Collections.EMPTY_LIST; - } - return Collections.unmodifiableList(options); - } - - /** - * Gets all options in the OPTRecord with a specific code. This returns a list - * of EDNSOptions. - */ - public - List getOptions(int code) { - if (options == null) { - return Collections.EMPTY_LIST; - } - List list = Collections.EMPTY_LIST; - for (Iterator it = options.iterator(); it.hasNext(); ) { - EDNSOption opt = (EDNSOption) it.next(); - if (opt.getCode() == code) { - if (list == Collections.EMPTY_LIST) { - list = new ArrayList(); - } - list.add(opt); - } - } - return list; - } - -} diff --git a/src/dorkbox/network/dns/records/PTRRecord.java b/src/dorkbox/network/dns/records/PTRRecord.java deleted file mode 100644 index ebb2575e..00000000 --- a/src/dorkbox/network/dns/records/PTRRecord.java +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * Pointer Record - maps a domain name representing an Internet Address to - * a hostname. - * - * @author Brian Wellington - */ - -public -class PTRRecord extends SingleCompressedNameBase { - - private static final long serialVersionUID = -8321636610425434192L; - - PTRRecord() {} - - @Override - DnsRecord getObject() { - return new PTRRecord(); - } - - /** - * Creates a new PTR Record with the given data - * - * @param target The name of the machine with this address - */ - public - PTRRecord(Name name, int dclass, long ttl, Name target) { - super(name, DnsRecordType.PTR, dclass, ttl, target, "target"); - } - - /** - * Gets the target of the PTR Record - */ - public - Name getTarget() { - return getSingleName(); - } - -} diff --git a/src/dorkbox/network/dns/records/PXRecord.java b/src/dorkbox/network/dns/records/PXRecord.java deleted file mode 100644 index 94d7b293..00000000 --- a/src/dorkbox/network/dns/records/PXRecord.java +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * X.400 mail mapping record. - * - * @author Brian Wellington - */ - -public -class PXRecord extends DnsRecord { - - private static final long serialVersionUID = 1811540008806660667L; - - private int preference; - private Name map822; - private Name mapX400; - - PXRecord() {} - - @Override - DnsRecord getObject() { - return new PXRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - preference = in.readU16(); - map822 = new Name(in); - mapX400 = new Name(in); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU16(preference); - map822.toWire(out, null, canonical); - mapX400.toWire(out, null, canonical); - } - - /** - * Converts the PX Record to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(preference); - sb.append(" "); - sb.append(map822); - sb.append(" "); - sb.append(mapX400); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - preference = st.getUInt16(); - map822 = st.getName(origin); - mapX400 = st.getName(origin); - } - - /** - * Creates an PX Record from the given data - * - * @param preference The preference of this mail address. - * @param map822 The RFC 822 component of the mail address. - * @param mapX400 The X.400 component of the mail address. - */ - public - PXRecord(Name name, int dclass, long ttl, int preference, Name map822, Name mapX400) { - super(name, DnsRecordType.PX, dclass, ttl); - - this.preference = checkU16("preference", preference); - this.map822 = checkName("map822", map822); - this.mapX400 = checkName("mapX400", mapX400); - } - - /** - * Gets the preference of the route. - */ - public - int getPreference() { - return preference; - } - - /** - * Gets the RFC 822 component of the mail address. - */ - public - Name getMap822() { - return map822; - } - - /** - * Gets the X.400 component of the mail address. - */ - public - Name getMapX400() { - return mapX400; - } - -} diff --git a/src/dorkbox/network/dns/records/RPRecord.java b/src/dorkbox/network/dns/records/RPRecord.java deleted file mode 100644 index 47c4173a..00000000 --- a/src/dorkbox/network/dns/records/RPRecord.java +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Responsible Person Record - lists the mail address of a responsible person - * and a domain where TXT records are available. - * - * @author Tom Scola (tscola@research.att.com) - * @author Brian Wellington - */ - -public -class RPRecord extends DnsRecord { - - private static final long serialVersionUID = 8124584364211337460L; - - private Name mailbox; - private Name textDomain; - - RPRecord() {} - - @Override - DnsRecord getObject() { - return new RPRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - mailbox = new Name(in); - textDomain = new Name(in); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - mailbox.toWire(out, null, canonical); - textDomain.toWire(out, null, canonical); - } - - /** - * Converts the RP Record to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(mailbox); - sb.append(" "); - sb.append(textDomain); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - mailbox = st.getName(origin); - textDomain = st.getName(origin); - } - - /** - * Creates an RP Record from the given data - * - * @param mailbox The responsible person - * @param textDomain The address where TXT records can be found - */ - public - RPRecord(Name name, int dclass, long ttl, Name mailbox, Name textDomain) { - super(name, DnsRecordType.RP, dclass, ttl); - - this.mailbox = checkName("mailbox", mailbox); - this.textDomain = checkName("textDomain", textDomain); - } - - /** - * Gets the mailbox address of the RP Record - */ - public - Name getMailbox() { - return mailbox; - } - - /** - * Gets the text domain info of the RP Record - */ - public - Name getTextDomain() { - return textDomain; - } - -} diff --git a/src/dorkbox/network/dns/records/RRSIGRecord.java b/src/dorkbox/network/dns/records/RRSIGRecord.java deleted file mode 100644 index efa02216..00000000 --- a/src/dorkbox/network/dns/records/RRSIGRecord.java +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.util.Date; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * Recource Record Signature - An RRSIG provides the digital signature of an - * RRset, so that the data can be authenticated by a DNSSEC-capable resolver. - * The signature is generated by a key contained in a DNSKEY Record. - * - * @author Brian Wellington - * @see RRset - * @see DNSSEC - * @see KEYRecord - */ - -public -class RRSIGRecord extends SIGBase { - - private static final long serialVersionUID = -2609150673537226317L; - - RRSIGRecord() {} - - @Override - DnsRecord getObject() { - return new RRSIGRecord(); - } - - /** - * Creates an RRSIG Record from the given data - * - * @param covered The RRset type covered by this signature - * @param alg The cryptographic algorithm of the key that generated the - * signature - * @param origttl The original TTL of the RRset - * @param expire The time at which the signature expires - * @param timeSigned The time at which this signature was generated - * @param footprint The footprint/key id of the signing key. - * @param signer The owner of the signing key - * @param signature Binary data representing the signature - */ - public - RRSIGRecord(Name name, - int dclass, - long ttl, - int covered, - int alg, - long origttl, - Date expire, - Date timeSigned, - int footprint, - Name signer, - byte[] signature) { - super(name, DnsRecordType.RRSIG, dclass, ttl, covered, alg, origttl, expire, timeSigned, footprint, signer, signature); - } - -} diff --git a/src/dorkbox/network/dns/records/RRset.java b/src/dorkbox/network/dns/records/RRset.java deleted file mode 100644 index 34cfc6b9..00000000 --- a/src/dorkbox/network/dns/records/RRset.java +++ /dev/null @@ -1,309 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * A set of Records with the same name, type, and class. Also included - * are all RRSIG records signing the data records. - * - * @author Brian Wellington - * @see DnsRecord - * @see RRSIGRecord - */ - -public -class RRset implements Serializable { - - private static final long serialVersionUID = -3270249290171239695L; - - /* - * rrs contains both normal and RRSIG records, with the RRSIG records - * at the end. - */ - private List resourceRecords; - private short nsigs; - private short position; - - /** - * Creates an RRset and sets its contents to the specified record - */ - public - RRset(DnsRecord record) { - this(); - safeAddRR(record); - } - - /** - * Creates an empty RRset - */ - public - RRset() { - resourceRecords = new ArrayList(1); - nsigs = 0; - position = 0; - } - - private - void safeAddRR(DnsRecord r) { - if (!(r instanceof RRSIGRecord)) { - if (nsigs == 0) { - resourceRecords.add(r); - } - else { - resourceRecords.add(resourceRecords.size() - nsigs, r); - } - } - else { - resourceRecords.add(r); - nsigs++; - } - } - - /** - * Creates an RRset with the contents of an existing RRset - */ - public - RRset(RRset rrset) { - synchronized (rrset) { - resourceRecords = (List) ((ArrayList) rrset.resourceRecords).clone(); - nsigs = rrset.nsigs; - position = rrset.position; - } - } - - /** - * Adds a Record to an RRset - */ - public synchronized - void addRR(DnsRecord r) { - if (resourceRecords.size() == 0) { - safeAddRR(r); - return; - } - DnsRecord first = first(); - if (!r.sameRRset(first)) { - throw new IllegalArgumentException("record does not match " + "rrset"); - } - - if (r.getTTL() != first.getTTL()) { - if (r.getTTL() > first.getTTL()) { - r = r.cloneRecord(); - r.setTTL(first.getTTL()); - } - else { - for (int i = 0; i < resourceRecords.size(); i++) { - DnsRecord tmp = (DnsRecord) resourceRecords.get(i); - tmp = tmp.cloneRecord(); - tmp.setTTL(r.getTTL()); - resourceRecords.set(i, tmp); - } - } - } - - if (!resourceRecords.contains(r)) { - safeAddRR(r); - } - } - - /** - * Returns the first record - * - * @throws IllegalStateException if the rrset is empty - */ - public synchronized - DnsRecord first() { - if (resourceRecords.size() == 0) { - throw new IllegalStateException("rrset is empty"); - } - return (DnsRecord) resourceRecords.get(0); - } - - /** - * Deletes a Record from an RRset - */ - public synchronized - void deleteRR(DnsRecord r) { - if (resourceRecords.remove(r) && (r instanceof RRSIGRecord)) { - nsigs--; - } - } - - /** - * Deletes all Records from an RRset - */ - public synchronized - void clear() { - resourceRecords.clear(); - position = 0; - nsigs = 0; - } - - /** - * Returns an Iterator listing all (data) records. - * - * @param cycle If true, cycle through the records so that each Iterator will - * start with a different record. - */ - public synchronized - Iterator rrs(boolean cycle) { - return iterator(true, cycle); - } - - private synchronized - Iterator iterator(boolean data, boolean cycle) { - int size, start, total; - - total = resourceRecords.size(); - - if (data) { - size = total - nsigs; - } - else { - size = nsigs; - } - if (size == 0) { - return Collections.EMPTY_LIST.iterator(); - } - - if (data) { - if (!cycle) { - start = 0; - } - else { - if (position >= size) { - position = 0; - } - start = position++; - } - } - else { - start = total - nsigs; - } - - List list = new ArrayList(size); - if (data) { - list.addAll(resourceRecords.subList(start, size)); - if (start != 0) { - list.addAll(resourceRecords.subList(0, start)); - } - } - else { - list.addAll(resourceRecords.subList(start, total)); - } - - return list.iterator(); - } - - /** - * Returns an Iterator listing all (data) records. This cycles through - * the records, so each Iterator will start with a different record. - */ - public synchronized - Iterator rrs() { - return iterator(true, true); - } - - /** - * Returns an Iterator listing all signature records - */ - public synchronized - Iterator sigs() { - return iterator(false, false); - } - - /** - * Returns the number of (data) records - */ - public synchronized - int size() { - return resourceRecords.size() - nsigs; - } - - /** - * Converts the RRset to a String - */ - @Override - public - String toString() { - if (resourceRecords.size() == 0) { - return ("{empty}"); - } - StringBuilder sb = new StringBuilder(); - sb.append("{ "); - sb.append(getName() + " "); - sb.append(getTTL() + " "); - sb.append(DnsClass.string(getDClass()) + " "); - sb.append(DnsRecordType.string(getType()) + " "); - sb.append(iteratorToString(iterator(true, false))); - if (nsigs > 0) { - sb.append(" sigs: "); - sb.append(iteratorToString(iterator(false, false))); - } - sb.append(" }"); - return sb.toString(); - } - - /** - * Returns the name of the records - * - * @see Name - */ - public - Name getName() { - return first().getName(); - } - - /** - * Returns the type of the records - * - * @see DnsRecordType - */ - public - int getType() { - return first().getRRsetType(); - } - - /** - * Returns the class of the records - * - * @see DnsClass - */ - public - int getDClass() { - return first().getDClass(); - } - - /** - * Returns the ttl of the records - */ - public synchronized - long getTTL() { - return first().getTTL(); - } - - private - String iteratorToString(Iterator it) { - StringBuilder sb = new StringBuilder(); - while (it.hasNext()) { - DnsRecord rr = (DnsRecord) it.next(); - sb.append("["); - rr.rdataToString(sb); - sb.append("]"); - if (it.hasNext()) { - sb.append(" "); - } - } - return sb.toString(); - } - -} diff --git a/src/dorkbox/network/dns/records/RTRecord.java b/src/dorkbox/network/dns/records/RTRecord.java deleted file mode 100644 index 96d2d77e..00000000 --- a/src/dorkbox/network/dns/records/RTRecord.java +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * Route Through Record - lists a route preference and intermediate host. - * - * @author Brian Wellington - */ - -public -class RTRecord extends U16NameBase { - - private static final long serialVersionUID = -3206215651648278098L; - - RTRecord() {} - - @Override - DnsRecord getObject() { - return new RTRecord(); - } - - /** - * Creates an RT Record from the given data - * - * @param preference The preference of the route. Smaller numbers indicate - * more preferred routes. - * @param intermediateHost The domain name of the host to use as a router. - */ - public - RTRecord(Name name, int dclass, long ttl, int preference, Name intermediateHost) { - super(name, DnsRecordType.RT, dclass, ttl, preference, "preference", intermediateHost, "intermediateHost"); - } - - /** - * Gets the preference of the route. - */ - public - int getPreference() { - return getU16Field(); - } - - /** - * Gets the host to use as a router. - */ - public - Name getIntermediateHost() { - return getNameField(); - } - -} diff --git a/src/dorkbox/network/dns/records/SIG0.java b/src/dorkbox/network/dns/records/SIG0.java deleted file mode 100644 index c55cab6f..00000000 --- a/src/dorkbox/network/dns/records/SIG0.java +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2001-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.security.PrivateKey; -import java.util.Date; - -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.utils.Options; - -/** - * Creates SIG(0) transaction signatures. - * - * @author Pasi Eronen - * @author Brian Wellington - */ - -public -class SIG0 { - - /** - * The default validity period for outgoing SIG(0) signed messages. - * Can be overriden by the sig0validity option. - */ - private static final short VALIDITY = 300; - - private - SIG0() { } - - /** - * Sign a dnsMessage with SIG(0). The DNS key and private key must refer to the - * same underlying cryptographic key. - * - * @param dnsMessage The dnsMessage to be signed - * @param key The DNSKEY record to use as part of signing - * @param privkey The PrivateKey to use when signing - * @param previous If this dnsMessage is a response, the SIG(0) from the query - */ - public static - void signMessage(DnsMessage dnsMessage, KEYRecord key, PrivateKey privkey, SIGRecord previous) throws DNSSEC.DNSSECException { - - int validity = Options.intValue("sig0validity"); - if (validity < 0) { - validity = VALIDITY; - } - - long now = System.currentTimeMillis(); - Date timeSigned = new Date(now); - Date timeExpires = new Date(now + validity * 1000); - - SIGRecord sig = DNSSEC.signMessage(dnsMessage, previous, key, privkey, timeSigned, timeExpires); - - dnsMessage.addRecord(sig, DnsSection.ADDITIONAL); - } - - /** - * Verify a dnsMessage using SIG(0). - * - * @param dnsMessage The dnsMessage to be signed - * @param b An array containing the dnsMessage in unparsed form. This is - * necessary since SIG(0) signs the dnsMessage in wire format, and we can't - * recreate the exact wire format (with the same name compression). - * @param key The KEY record to verify the signature with. - * @param previous If this dnsMessage is a response, the SIG(0) from the query - */ - public static - void verifyMessage(DnsMessage dnsMessage, byte[] b, KEYRecord key, SIGRecord previous) throws DNSSEC.DNSSECException { - SIGRecord sig = null; - DnsRecord[] additional = dnsMessage.getSectionArray(DnsSection.ADDITIONAL); - for (int i = 0; i < additional.length; i++) { - if (additional[i].getType() != DnsRecordType.SIG) { - continue; - } - if (((SIGRecord) additional[i]).getTypeCovered() != 0) { - continue; - } - sig = (SIGRecord) additional[i]; - break; - } - DNSSEC.verifyMessage(dnsMessage, b, sig, previous, key); - } - -} diff --git a/src/dorkbox/network/dns/records/SIGBase.java b/src/dorkbox/network/dns/records/SIGBase.java deleted file mode 100644 index f72016bf..00000000 --- a/src/dorkbox/network/dns/records/SIGBase.java +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.util.Date; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.FormattedTime; -import dorkbox.network.dns.utils.Options; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.util.Base64Fast; -import dorkbox.util.OS; - -/** - * The base class for SIG/RRSIG records, which have identical formats - * - * @author Brian Wellington - */ - -abstract -class SIGBase extends DnsRecord { - - private static final long serialVersionUID = -3738444391533812369L; - - protected int covered; - protected int alg, labels; - protected long origttl; - protected Date expire, timeSigned; - protected int footprint; - protected Name signer; - protected byte[] signature; - - protected - SIGBase() {} - - public - SIGBase(Name name, - int type, - int dclass, - long ttl, - int covered, - int alg, - long origttl, - Date expire, - Date timeSigned, - int footprint, - Name signer, - byte[] signature) { - super(name, type, dclass, ttl); - DnsRecordType.check(covered); - TTL.check(origttl); - this.covered = covered; - this.alg = checkU8("alg", alg); - this.labels = name.labels() - 1; - if (name.isWild()) { - this.labels--; - } - this.origttl = origttl; - this.expire = expire; - this.timeSigned = timeSigned; - this.footprint = checkU16("footprint", footprint); - this.signer = checkName("signer", signer); - this.signature = signature; - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - covered = in.readU16(); - alg = in.readU8(); - labels = in.readU8(); - origttl = in.readU32(); - expire = new Date(1000 * in.readU32()); - timeSigned = new Date(1000 * in.readU32()); - footprint = in.readU16(); - signer = new Name(in); - signature = in.readByteArray(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU16(covered); - out.writeU8(alg); - out.writeU8(labels); - out.writeU32(origttl); - out.writeU32(expire.getTime() / 1000); - out.writeU32(timeSigned.getTime() / 1000); - out.writeU16(footprint); - signer.toWire(out, null, canonical); - out.writeByteArray(signature); - } - - /** - * Converts the RRSIG/SIG Record to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(DnsRecordType.string(covered)); - sb.append(" "); - sb.append(alg); - sb.append(" "); - sb.append(labels); - sb.append(" "); - sb.append(origttl); - sb.append(" "); - if (Options.check("multiline")) { - sb.append("(\n\t"); - } - sb.append(FormattedTime.format(expire)); - sb.append(" "); - sb.append(FormattedTime.format(timeSigned)); - sb.append(" "); - sb.append(footprint); - sb.append(" "); - sb.append(signer); - if (Options.check("multiline")) { - sb.append(OS.LINE_SEPARATOR); - sb.append(Base64Fast.formatString(Base64Fast.encode2(signature), 64, "\t", true)); - } - else { - sb.append(" "); - sb.append(Base64Fast.encode2(signature)); - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - String typeString = st.getString(); - covered = DnsRecordType.value(typeString); - if (covered < 0) { - throw st.exception("Invalid type: " + typeString); - } - String algString = st.getString(); - alg = DNSSEC.Algorithm.value(algString); - if (alg < 0) { - throw st.exception("Invalid algorithm: " + algString); - } - labels = st.getUInt8(); - origttl = st.getTTL(); - expire = FormattedTime.parse(st.getString()); - timeSigned = FormattedTime.parse(st.getString()); - footprint = st.getUInt16(); - signer = st.getName(origin); - signature = st.getBase64(); - } - - /** - * Returns the RRset type covered by this signature - */ - public - int getTypeCovered() { - return covered; - } - - /** - * Returns the cryptographic algorithm of the key that generated the signature - */ - public - int getAlgorithm() { - return alg; - } - - /** - * Returns the number of labels in the signed domain name. This may be - * different than the record's domain name if the record is a wildcard - * record. - */ - public - int getLabels() { - return labels; - } - - /** - * Returns the original TTL of the RRset - */ - public - long getOrigTTL() { - return origttl; - } - - /** - * Returns the time at which the signature expires - */ - public - Date getExpire() { - return expire; - } - - /** - * Returns the time at which this signature was generated - */ - public - Date getTimeSigned() { - return timeSigned; - } - - /** - * Returns The footprint/key id of the signing key. - */ - public - int getFootprint() { - return footprint; - } - - /** - * Returns the owner of the signing key - */ - public - Name getSigner() { - return signer; - } - - /** - * Returns the binary data representing the signature - */ - public - byte[] getSignature() { - return signature; - } - - void setSignature(byte[] signature) { - this.signature = signature; - } - -} diff --git a/src/dorkbox/network/dns/records/SIGRecord.java b/src/dorkbox/network/dns/records/SIGRecord.java deleted file mode 100644 index c0984d06..00000000 --- a/src/dorkbox/network/dns/records/SIGRecord.java +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.util.Date; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * Signature - A SIG provides the digital signature of an RRset, so that - * the data can be authenticated by a DNSSEC-capable resolver. The - * signature is usually generated by a key contained in a KEYRecord - * - * @author Brian Wellington - * @see RRset - * @see DNSSEC - * @see KEYRecord - */ - -public -class SIGRecord extends SIGBase { - - private static final long serialVersionUID = 4963556060953589058L; - - SIGRecord() {} - - @Override - DnsRecord getObject() { - return new SIGRecord(); - } - - /** - * Creates an SIG Record from the given data - * - * @param covered The RRset type covered by this signature - * @param alg The cryptographic algorithm of the key that generated the - * signature - * @param origttl The original TTL of the RRset - * @param expire The time at which the signature expires - * @param timeSigned The time at which this signature was generated - * @param footprint The footprint/key id of the signing key. - * @param signer The owner of the signing key - * @param signature Binary data representing the signature - */ - public - SIGRecord(Name name, - int dclass, - long ttl, - int covered, - int alg, - long origttl, - Date expire, - Date timeSigned, - int footprint, - Name signer, - byte[] signature) { - super(name, DnsRecordType.SIG, dclass, ttl, covered, alg, origttl, expire, timeSigned, footprint, signer, signature); - } - -} diff --git a/src/dorkbox/network/dns/records/SMIMEARecord.java b/src/dorkbox/network/dns/records/SMIMEARecord.java deleted file mode 100644 index 39a505ff..00000000 --- a/src/dorkbox/network/dns/records/SMIMEARecord.java +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.network.dns.utils.base16; - -/** - * S/MIME cert association, draft-ietf-dane-smime. - * - * @author Brian Wellington - */ - -public -class SMIMEARecord extends DnsRecord { - - private static final long serialVersionUID = 1640247915216425235L; - -// Note; these are copied from the TLSA type. - private int certificateUsage; - private int selector; - private int matchingType; - private byte[] certificateAssociationData; - - - public static - class CertificateUsage { - public static final int CA_CONSTRAINT = 0; - public static final int SERVICE_CERTIFICATE_CONSTRAINT = 1; - public static final int TRUST_ANCHOR_ASSERTION = 2; - public static final int DOMAIN_ISSUED_CERTIFICATE = 3; - private - CertificateUsage() {} - } - - - public static - class Selector { - /** - * Full certificate; the Certificate binary structure defined in - * [RFC5280] - */ - public static final int FULL_CERTIFICATE = 0; - /** - * SubjectPublicKeyInfo; DER-encoded binary structure defined in - * [RFC5280] - */ - public static final int SUBJECT_PUBLIC_KEY_INFO = 1; - - private - Selector() {} - } - - - public static - class MatchingType { - /** - * Exact match on selected content - */ - public static final int EXACT = 0; - /** - * SHA-256 hash of selected content [RFC6234] - */ - public static final int SHA256 = 1; - /** - * SHA-512 hash of selected content [RFC6234] - */ - public static final int SHA512 = 2; - - private - MatchingType() {} - } - - SMIMEARecord() {} - - @Override - DnsRecord getObject() { - return new SMIMEARecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - certificateUsage = in.readU8(); - selector = in.readU8(); - matchingType = in.readU8(); - certificateAssociationData = in.readByteArray(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU8(certificateUsage); - out.writeU8(selector); - out.writeU8(matchingType); - out.writeByteArray(certificateAssociationData); - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(certificateUsage); - sb.append(" "); - sb.append(selector); - sb.append(" "); - sb.append(matchingType); - sb.append(" "); - sb.append(base16.toString(certificateAssociationData)); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - certificateUsage = st.getUInt8(); - selector = st.getUInt8(); - matchingType = st.getUInt8(); - certificateAssociationData = st.getHex(); - } - - /** - * Creates an SMIMEA Record from the given data - * - * @param certificateUsage The provided association that will be used to - * match the certificate presented in the S/MIME handshake. - * @param selector The part of the S/MIME certificate presented by the server - * that will be matched against the association data. - * @param matchingType How the certificate association is presented. - * @param certificateAssociationData The "certificate association data" to be - * matched. - */ - public - SMIMEARecord(Name name, int dclass, long ttl, int certificateUsage, int selector, int matchingType, byte[] certificateAssociationData) { - super(name, DnsRecordType.SMIMEA, dclass, ttl); - this.certificateUsage = checkU8("certificateUsage", certificateUsage); - this.selector = checkU8("selector", selector); - this.matchingType = checkU8("matchingType", matchingType); - this.certificateAssociationData = checkByteArrayLength("certificateAssociationData", certificateAssociationData, 0xFFFF); - } - - /** - * Returns the certificate usage of the SMIMEA record - */ - public - int getCertificateUsage() { - return certificateUsage; - } - - /** - * Returns the selector of the SMIMEA record - */ - public - int getSelector() { - return selector; - } - - /** - * Returns the matching type of the SMIMEA record - */ - public - int getMatchingType() { - return matchingType; - } - - /** - * Returns the certificate associate data of this SMIMEA record - */ - public final - byte[] getCertificateAssociationData() { - return certificateAssociationData; - } - -} diff --git a/src/dorkbox/network/dns/records/SOARecord.java b/src/dorkbox/network/dns/records/SOARecord.java deleted file mode 100644 index 0bff3b60..00000000 --- a/src/dorkbox/network/dns/records/SOARecord.java +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Options; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Start of Authority - describes properties of a zone. - * - * @author Brian Wellington - */ - -public -class SOARecord extends DnsRecord { - - private static final long serialVersionUID = 1049740098229303931L; - - private Name host, admin; - private long serial, refresh, retry, expire, minimum; - - SOARecord() {} - - @Override - DnsRecord getObject() { - return new SOARecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - host = new Name(in); - admin = new Name(in); - serial = in.readU32(); - refresh = in.readU32(); - retry = in.readU32(); - expire = in.readU32(); - minimum = in.readU32(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - host.toWire(out, c, canonical); - admin.toWire(out, c, canonical); - out.writeU32(serial); - out.writeU32(refresh); - out.writeU32(retry); - out.writeU32(expire); - out.writeU32(minimum); - } - - /** - * Convert to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(host); - sb.append(" "); - sb.append(admin); - - if (Options.check("multiline")) { - sb.append(" (\n\t\t\t\t\t"); - sb.append(serial); - sb.append("\t; serial\n\t\t\t\t\t"); - sb.append(refresh); - sb.append("\t; refresh\n\t\t\t\t\t"); - sb.append(retry); - sb.append("\t; retry\n\t\t\t\t\t"); - sb.append(expire); - sb.append("\t; expire\n\t\t\t\t\t"); - sb.append(minimum); - sb.append(" )\t; minimum"); - } - else { - sb.append(" "); - sb.append(serial); - sb.append(" "); - sb.append(refresh); - sb.append(" "); - sb.append(retry); - sb.append(" "); - sb.append(expire); - sb.append(" "); - sb.append(minimum); - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - host = st.getName(origin); - admin = st.getName(origin); - serial = st.getUInt32(); - refresh = st.getTTLLike(); - retry = st.getTTLLike(); - expire = st.getTTLLike(); - minimum = st.getTTLLike(); - } - - /** - * Creates an SOA Record from the given data - * - * @param host The primary name server for the zone - * @param admin The zone administrator's address - * @param serial The zone's serial number - * @param refresh The amount of time until a secondary checks for a new serial - * number - * @param retry The amount of time between a secondary's checks for a new - * serial number - * @param expire The amount of time until a secondary expires a zone - * @param minimum The minimum TTL for records in the zone - */ - public - SOARecord(Name name, int dclass, long ttl, Name host, Name admin, long serial, long refresh, long retry, long expire, long minimum) { - super(name, DnsRecordType.SOA, dclass, ttl); - this.host = checkName("host", host); - this.admin = checkName("admin", admin); - this.serial = checkU32("serial", serial); - this.refresh = checkU32("refresh", refresh); - this.retry = checkU32("retry", retry); - this.expire = checkU32("expire", expire); - this.minimum = checkU32("minimum", minimum); - } - - /** - * Returns the primary name server - */ - public - Name getHost() { - return host; - } - - /** - * Returns the zone administrator's address - */ - public - Name getAdmin() { - return admin; - } - - /** - * Returns the zone's serial number - */ - public - long getSerial() { - return serial; - } - - /** - * Returns the zone refresh interval - */ - public - long getRefresh() { - return refresh; - } - - /** - * Returns the zone retry interval - */ - public - long getRetry() { - return retry; - } - - /** - * Returns the time until a secondary expires a zone - */ - public - long getExpire() { - return expire; - } - - /** - * Returns the minimum TTL for records in the zone - */ - public - long getMinimum() { - return minimum; - } - -} diff --git a/src/dorkbox/network/dns/records/SPFRecord.java b/src/dorkbox/network/dns/records/SPFRecord.java deleted file mode 100644 index b82cd664..00000000 --- a/src/dorkbox/network/dns/records/SPFRecord.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.util.List; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * Sender Policy Framework (RFC 4408, experimental) - * - * @author Brian Wellington - */ - -public -class SPFRecord extends TXTBase { - - private static final long serialVersionUID = -2100754352801658722L; - - SPFRecord() {} - - @Override - DnsRecord getObject() { - return new SPFRecord(); - } - - /** - * Creates a SPF Record from the given data - * - * @param strings The text strings - * - * @throws IllegalArgumentException One of the strings has invalid escapes - */ - public - SPFRecord(Name name, int dclass, long ttl, List strings) { - super(name, DnsRecordType.SPF, dclass, ttl, strings); - } - - /** - * Creates a SPF Record from the given data - * - * @param string One text string - * - * @throws IllegalArgumentException The string has invalid escapes - */ - public - SPFRecord(Name name, int dclass, long ttl, String string) { - super(name, DnsRecordType.SPF, dclass, ttl, string); - } - -} diff --git a/src/dorkbox/network/dns/records/SRVRecord.java b/src/dorkbox/network/dns/records/SRVRecord.java deleted file mode 100644 index e2eac878..00000000 --- a/src/dorkbox/network/dns/records/SRVRecord.java +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Server Selection Record - finds hosts running services in a domain. An - * SRV record will normally be named _<service>._<protocol>.domain - * - examples would be _sips._tcp.example.org (for the secure SIP protocol) and - * _http._tcp.example.com (if HTTP used SRV records) - * - * @author Brian Wellington - */ - -public -class SRVRecord extends DnsRecord { - - private static final long serialVersionUID = -3886460132387522052L; - - private int priority, weight, port; - private Name target; - - SRVRecord() {} - - @Override - DnsRecord getObject() { - return new SRVRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - priority = in.readU16(); - weight = in.readU16(); - port = in.readU16(); - target = new Name(in); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU16(priority); - out.writeU16(weight); - out.writeU16(port); - target.toWire(out, null, canonical); - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(priority + " "); - sb.append(weight + " "); - sb.append(port + " "); - sb.append(target); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - priority = st.getUInt16(); - weight = st.getUInt16(); - port = st.getUInt16(); - target = st.getName(origin); - } - - @Override - public - Name getAdditionalName() { - return target; - } - - /** - * Creates an SRV Record from the given data - * - * @param priority The priority of this SRV. Records with lower priority - * are preferred. - * @param weight The weight, used to select between records at the same - * priority. - * @param port The TCP/UDP port that the service uses - * @param target The host running the service - */ - public - SRVRecord(Name name, int dclass, long ttl, int priority, int weight, int port, Name target) { - super(name, DnsRecordType.SRV, dclass, ttl); - this.priority = checkU16("priority", priority); - this.weight = checkU16("weight", weight); - this.port = checkU16("port", port); - this.target = checkName("target", target); - } - - /** - * Returns the priority - */ - public - int getPriority() { - return priority; - } - - /** - * Returns the weight - */ - public - int getWeight() { - return weight; - } - - /** - * Returns the port that the service runs on - */ - public - int getPort() { - return port; - } - - /** - * Returns the host running that the service - */ - public - Name getTarget() { - return target; - } - -} diff --git a/src/dorkbox/network/dns/records/SSHFPRecord.java b/src/dorkbox/network/dns/records/SSHFPRecord.java deleted file mode 100644 index 2986d1be..00000000 --- a/src/dorkbox/network/dns/records/SSHFPRecord.java +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.network.dns.utils.base16; - -/** - * SSH Fingerprint - stores the fingerprint of an SSH host key. - * - * @author Brian Wellington - */ - -public -class SSHFPRecord extends DnsRecord { - - private static final long serialVersionUID = -8104701402654687025L; - private int alg; - private int digestType; - private byte[] fingerprint; - - - public static - class Algorithm { - public static final int RSA = 1; - public static final int DSS = 2; - private - Algorithm() {} - } - - - public static - class Digest { - public static final int SHA1 = 1; - - private - Digest() {} - } - - SSHFPRecord() {} - - @Override - DnsRecord getObject() { - return new SSHFPRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - alg = in.readU8(); - digestType = in.readU8(); - fingerprint = in.readByteArray(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU8(alg); - out.writeU8(digestType); - out.writeByteArray(fingerprint); - } - - @Override - void rrToString(StringBuilder sb) { - sb.append(alg); - sb.append(" "); - sb.append(digestType); - sb.append(" "); - sb.append(base16.toString(fingerprint)); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - alg = st.getUInt8(); - digestType = st.getUInt8(); - fingerprint = st.getHex(true); - } - - /** - * Creates an SSHFP Record from the given data. - * - * @param alg The public key's algorithm. - * @param digestType The public key's digest type. - * @param fingerprint The public key's fingerprint. - */ - public - SSHFPRecord(Name name, int dclass, long ttl, int alg, int digestType, byte[] fingerprint) { - super(name, DnsRecordType.SSHFP, dclass, ttl); - this.alg = checkU8("alg", alg); - this.digestType = checkU8("digestType", digestType); - this.fingerprint = fingerprint; - } - - /** - * Returns the public key's algorithm. - */ - public - int getAlgorithm() { - return alg; - } - - /** - * Returns the public key's digest type. - */ - public - int getDigestType() { - return digestType; - } - - /** - * Returns the fingerprint - */ - public - byte[] getFingerPrint() { - return fingerprint; - } - -} diff --git a/src/dorkbox/network/dns/records/SingleCompressedNameBase.java b/src/dorkbox/network/dns/records/SingleCompressedNameBase.java deleted file mode 100644 index 8eef22d3..00000000 --- a/src/dorkbox/network/dns/records/SingleCompressedNameBase.java +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; - -/** - * Implements common functionality for the many record types whose format - * is a single compressed name. - * - * @author Brian Wellington - */ - -abstract -class SingleCompressedNameBase extends SingleNameBase { - - private static final long serialVersionUID = -236435396815460677L; - - protected - SingleCompressedNameBase() {} - - protected - SingleCompressedNameBase(Name name, int type, int dclass, long ttl, Name singleName, String description) { - super(name, type, dclass, ttl, singleName, description); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - singleName.toWire(out, c, canonical); - } - -} diff --git a/src/dorkbox/network/dns/records/SingleNameBase.java b/src/dorkbox/network/dns/records/SingleNameBase.java deleted file mode 100644 index 9ddaf47d..00000000 --- a/src/dorkbox/network/dns/records/SingleNameBase.java +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Implements common functionality for the many record types whose format - * is a single name. - * - * @author Brian Wellington - */ - -abstract -class SingleNameBase extends DnsRecord { - - private static final long serialVersionUID = -18595042501413L; - - protected Name singleName; - - protected - SingleNameBase() {} - - protected - SingleNameBase(Name name, int type, int dclass, long ttl) { - super(name, type, dclass, ttl); - } - - protected - SingleNameBase(Name name, int type, int dclass, long ttl, Name singleName, String description) { - super(name, type, dclass, ttl); - this.singleName = checkName(description, singleName); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - singleName = new Name(in); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - singleName.toWire(out, null, canonical); - } - - @Override - void rrToString(StringBuilder sb) { - sb.append(singleName.toString()); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - singleName = st.getName(origin); - } - - protected - Name getSingleName() { - return singleName; - } - -} diff --git a/src/dorkbox/network/dns/records/TKEYRecord.java b/src/dorkbox/network/dns/records/TKEYRecord.java deleted file mode 100644 index bd8910bf..00000000 --- a/src/dorkbox/network/dns/records/TKEYRecord.java +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.util.Date; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.utils.FormattedTime; -import dorkbox.network.dns.utils.Options; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.util.Base64Fast; -import dorkbox.util.OS; - -/** - * Transaction Key - used to compute and/or securely transport a shared - * secret to be used with TSIG. - * - * @author Brian Wellington - * @see TSIG - */ - -public -class TKEYRecord extends DnsRecord { - - private static final long serialVersionUID = 8828458121926391756L; - - private Name alg; - private Date timeInception; - private Date timeExpire; - private int mode, error; - private byte[] key; - private byte[] other; - - /** - * The key is assigned by the server (unimplemented) - */ - public static final int SERVERASSIGNED = 1; - - /** - * The key is computed using a Diffie-Hellman key exchange - */ - public static final int DIFFIEHELLMAN = 2; - - /** - * The key is computed using GSS_API (unimplemented) - */ - public static final int GSSAPI = 3; - - /** - * The key is assigned by the resolver (unimplemented) - */ - public static final int RESOLVERASSIGNED = 4; - - /** - * The key should be deleted - */ - public static final int DELETE = 5; - - TKEYRecord() {} - - @Override - DnsRecord getObject() { - return new TKEYRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - alg = new Name(in); - timeInception = new Date(1000 * in.readU32()); - timeExpire = new Date(1000 * in.readU32()); - mode = in.readU16(); - error = in.readU16(); - - int keylen = in.readU16(); - if (keylen > 0) { - key = in.readByteArray(keylen); - } - else { - key = null; - } - - int otherlen = in.readU16(); - if (otherlen > 0) { - other = in.readByteArray(otherlen); - } - else { - other = null; - } - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - alg.toWire(out, null, canonical); - - out.writeU32(timeInception.getTime() / 1000); - out.writeU32(timeExpire.getTime() / 1000); - - out.writeU16(mode); - out.writeU16(error); - - if (key != null) { - out.writeU16(key.length); - out.writeByteArray(key); - } - else { - out.writeU16(0); - } - - if (other != null) { - out.writeU16(other.length); - out.writeByteArray(other); - } - else { - out.writeU16(0); - } - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(alg); - sb.append(" "); - if (Options.check("multiline")) { - sb.append("(") - .append(OS.LINE_SEPARATOR) - .append("\t"); - } - sb.append(FormattedTime.format(timeInception)); - sb.append(" "); - sb.append(FormattedTime.format(timeExpire)); - sb.append(" "); - sb.append(modeString()); - sb.append(" "); - sb.append(DnsResponseCode.TSIGstring(error)); - if (Options.check("multiline")) { - sb.append(OS.LINE_SEPARATOR); - if (key != null) { - sb.append(Base64Fast.formatString(Base64Fast.encode2(key), 64, "\t", true)); - sb.append(OS.LINE_SEPARATOR); - } - if (other != null) { - sb.append(Base64Fast.formatString(Base64Fast.encode2(other), 64, "\t", true)); - } - sb.append(" )"); - } - else { - sb.append(" "); - if (key != null) { - sb.append("\t"); - sb.append(Base64Fast.encode2(key)); - - sb.append(" "); - } - if (other != null) { - sb.append("\t"); - sb.append(Base64Fast.encode2(other)); - } - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - throw st.exception("no text format defined for TKEY"); - } - - protected - String modeString() { - switch (mode) { - case SERVERASSIGNED: - return "SERVERASSIGNED"; - case DIFFIEHELLMAN: - return "DIFFIEHELLMAN"; - case GSSAPI: - return "GSSAPI"; - case RESOLVERASSIGNED: - return "RESOLVERASSIGNED"; - case DELETE: - return "DELETE"; - default: - return Integer.toString(mode); - } - } - - /** - * Creates a TKEY Record from the given data. - * - * @param alg The shared key's algorithm - * @param timeInception The beginning of the validity period of the shared - * secret or keying material - * @param timeExpire The end of the validity period of the shared - * secret or keying material - * @param mode The mode of key agreement - * @param error The extended error field. Should be 0 in queries - * @param key The shared secret - * @param other The other data field. Currently unused - * responses. - */ - public - TKEYRecord(Name name, - int dclass, - long ttl, - Name alg, - Date timeInception, - Date timeExpire, - int mode, - int error, - byte[] key, - byte other[]) { - super(name, DnsRecordType.TKEY, dclass, ttl); - this.alg = checkName("alg", alg); - this.timeInception = timeInception; - this.timeExpire = timeExpire; - this.mode = checkU16("mode", mode); - this.error = checkU16("error", error); - this.key = key; - this.other = other; - } - - /** - * Returns the shared key's algorithm - */ - public - Name getAlgorithm() { - return alg; - } - - /** - * Returns the beginning of the validity period of the shared secret or - * keying material - */ - public - Date getTimeInception() { - return timeInception; - } - - /** - * Returns the end of the validity period of the shared secret or - * keying material - */ - public - Date getTimeExpire() { - return timeExpire; - } - - /** - * Returns the key agreement mode - */ - public - int getMode() { - return mode; - } - - /** - * Returns the extended error - */ - public - int getError() { - return error; - } - - /** - * Returns the shared secret or keying material - */ - public - byte[] getKey() { - return key; - } - - /** - * Returns the other data - */ - public - byte[] getOther() { - return other; - } - -} diff --git a/src/dorkbox/network/dns/records/TLSARecord.java b/src/dorkbox/network/dns/records/TLSARecord.java deleted file mode 100644 index 3ec1b089..00000000 --- a/src/dorkbox/network/dns/records/TLSARecord.java +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.network.dns.utils.base16; - -/** - * Transport Layer Security Authentication - * - * @author Brian Wellington - */ - -public -class TLSARecord extends DnsRecord { - - private static final long serialVersionUID = 356494267028580169L; - private int certificateUsage; - private int selector; - private int matchingType; - private byte[] certificateAssociationData; - - - public static - class CertificateUsage { - public static final int CA_CONSTRAINT = 0; - public static final int SERVICE_CERTIFICATE_CONSTRAINT = 1; - public static final int TRUST_ANCHOR_ASSERTION = 2; - public static final int DOMAIN_ISSUED_CERTIFICATE = 3; - private - CertificateUsage() {} - } - - - public static - class Selector { - /** - * Full certificate; the Certificate binary structure defined in - * [RFC5280] - */ - public static final int FULL_CERTIFICATE = 0; - /** - * SubjectPublicKeyInfo; DER-encoded binary structure defined in - * [RFC5280] - */ - public static final int SUBJECT_PUBLIC_KEY_INFO = 1; - - private - Selector() {} - } - - - public static - class MatchingType { - /** - * Exact match on selected content - */ - public static final int EXACT = 0; - /** - * SHA-256 hash of selected content [RFC6234] - */ - public static final int SHA256 = 1; - /** - * SHA-512 hash of selected content [RFC6234] - */ - public static final int SHA512 = 2; - - private - MatchingType() {} - } - - TLSARecord() {} - - @Override - DnsRecord getObject() { - return new TLSARecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - certificateUsage = in.readU8(); - selector = in.readU8(); - matchingType = in.readU8(); - certificateAssociationData = in.readByteArray(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU8(certificateUsage); - out.writeU8(selector); - out.writeU8(matchingType); - out.writeByteArray(certificateAssociationData); - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(certificateUsage); - sb.append(" "); - sb.append(selector); - sb.append(" "); - sb.append(matchingType); - sb.append(" "); - sb.append(base16.toString(certificateAssociationData)); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - certificateUsage = st.getUInt8(); - selector = st.getUInt8(); - matchingType = st.getUInt8(); - certificateAssociationData = st.getHex(); - } - - /** - * Creates an TLSA Record from the given data - * - * @param certificateUsage The provided association that will be used to - * match the certificate presented in the TLS handshake. - * @param selector The part of the TLS certificate presented by the server - * that will be matched against the association data. - * @param matchingType How the certificate association is presented. - * @param certificateAssociationData The "certificate association data" to be - * matched. - */ - public - TLSARecord(Name name, int dclass, long ttl, int certificateUsage, int selector, int matchingType, byte[] certificateAssociationData) { - super(name, DnsRecordType.TLSA, dclass, ttl); - this.certificateUsage = checkU8("certificateUsage", certificateUsage); - this.selector = checkU8("selector", selector); - this.matchingType = checkU8("matchingType", matchingType); - this.certificateAssociationData = checkByteArrayLength("certificateAssociationData", certificateAssociationData, 0xFFFF); - } - - /** - * Returns the certificate usage of the TLSA record - */ - public - int getCertificateUsage() { - return certificateUsage; - } - - /** - * Returns the selector of the TLSA record - */ - public - int getSelector() { - return selector; - } - - /** - * Returns the matching type of the TLSA record - */ - public - int getMatchingType() { - return matchingType; - } - - /** - * Returns the certificate associate data of this TLSA record - */ - public final - byte[] getCertificateAssociationData() { - return certificateAssociationData; - } - -} diff --git a/src/dorkbox/network/dns/records/TSIG.java b/src/dorkbox/network/dns/records/TSIG.java deleted file mode 100644 index 0cad79e0..00000000 --- a/src/dorkbox/network/dns/records/TSIG.java +++ /dev/null @@ -1,777 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.util.Arrays; -import java.util.Date; - -import javax.crypto.Mac; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import com.esotericsoftware.kryo.util.ObjectMap; - -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Options; -import dorkbox.util.Base64Fast; - -/** - * Transaction signature handling. This class generates and verifies - * TSIG records on messages, which provide transaction security. - * - * @author Brian Wellington - * @see TSIGRecord - */ - -@SuppressWarnings("WeakerAccess") -public -class TSIG { - - /** - * The domain name representing the HMAC-MD5 algorithm. - */ - public static final Name HMAC_MD5 = Name.fromConstantString("HMAC-MD5.SIG-ALG.REG.INT."); - - /** - * The domain name representing the HMAC-MD5 algorithm (deprecated). - */ - public static final Name HMAC = HMAC_MD5; - - /** - * The domain name representing the HMAC-SHA1 algorithm. - */ - public static final Name HMAC_SHA1 = Name.fromConstantString("hmac-sha1."); - - /** - * The domain name representing the HMAC-SHA224 algorithm. - * Note that SHA224 is not supported by Java out-of-the-box, this requires use - * of a third party provider like BouncyCastle.org. - */ - public static final Name HMAC_SHA224 = Name.fromConstantString("hmac-sha224."); - - /** - * The domain name representing the HMAC-SHA256 algorithm. - */ - public static final Name HMAC_SHA256 = Name.fromConstantString("hmac-sha256."); - - /** - * The domain name representing the HMAC-SHA384 algorithm. - */ - public static final Name HMAC_SHA384 = Name.fromConstantString("hmac-sha384."); - - /** - * The domain name representing the HMAC-SHA512 algorithm. - */ - public static final Name HMAC_SHA512 = Name.fromConstantString("hmac-sha512."); - - private static final ObjectMap algMap = new ObjectMap(); - - /** - * The default fudge value for outgoing packets. Can be overridden by the - * tsigfudge option. - */ - public static final short FUDGE = 300; - private Name name, alg; - private Mac hmac; - - static { - algMap.put(HMAC_MD5, "HmacMD5"); - algMap.put(HMAC_SHA1, "HmacSHA1"); - algMap.put(HMAC_SHA224, "HmacSHA224"); - algMap.put(HMAC_SHA256, "HmacSHA256"); - algMap.put(HMAC_SHA384, "HmacSHA384"); - algMap.put(HMAC_SHA512, "HmacSHA512"); - } - - /** - * Verifies the data (computes the secure hash and compares it to the input) - * - * @param mac The HMAC generator - * @param signature The signature to compare against - * - * @return true if the signature matches, false otherwise - */ - private static - boolean verify(Mac mac, byte[] signature) { - return verify(mac, signature, false); - } - - /** - * Verifies the data (computes the secure hash and compares it to the input) - * - * @param mac The HMAC generator - * @param signature The signature to compare against - * @param truncation_ok If true, the signature may be truncated; only the - * number of bytes in the provided signature are compared. - * - * @return true if the signature matches, false otherwise - */ - private static - boolean verify(Mac mac, byte[] signature, boolean truncation_ok) { - byte[] expected = mac.doFinal(); - if (truncation_ok && signature.length < expected.length) { - byte[] truncated = new byte[signature.length]; - System.arraycopy(expected, 0, truncated, 0, truncated.length); - expected = truncated; - } - return Arrays.equals(signature, expected); - } - - /** - * Creates a new TSIG key, which can be used to sign or verify a message. - * - * @param algorithm The algorithm of the shared key. - * @param name The name of the shared key. - * @param key The shared key. - */ - public - TSIG(Name algorithm, Name name, SecretKey key) { - this.name = name; - this.alg = algorithm; - String macAlgorithm = nameToAlgorithm(algorithm); - init_hmac(macAlgorithm, key); - } - - public static - String nameToAlgorithm(Name name) { - String alg = algMap.get(name); - if (alg != null) { - return alg; - } - throw new IllegalArgumentException("Unknown algorithm"); - } - - private - void init_hmac(String macAlgorithm, SecretKey key) { - try { - hmac = Mac.getInstance(macAlgorithm); - hmac.init(key); - } catch (GeneralSecurityException ex) { - throw new IllegalArgumentException("Caught security " + "exception setting up " + "HMAC."); - } - } - - /** - * Creates a new TSIG key from a pre-initialized Mac instance. - * This assumes that init() has already been called on the mac - * to set up the key. - * - * @param mac The JCE HMAC object - * @param name The name of the key - */ - public - TSIG(Mac mac, Name name) { - this.name = name; - this.hmac = mac; - this.alg = algorithmToName(mac.getAlgorithm()); - } - - public static - Name algorithmToName(String alg) { - - // false identity check because it's string comparisons. - Name foundKey = algMap.findKey(alg, false); - if (foundKey != null) { - return foundKey; - } - - throw new IllegalArgumentException("Unknown algorithm"); - } - - /** - * Creates a new TSIG key with the hmac-md5 algorithm, which can be used to - * sign or verify a message. - * - * @param name The name of the shared key. - * @param key The shared key's data. - */ - public - TSIG(Name name, byte[] key) { - this(HMAC_MD5, name, key); - } - - /** - * Creates a new TSIG key, which can be used to sign or verify a message. - * - * @param algorithm The algorithm of the shared key. - * @param name The name of the shared key. - * @param keyBytes The shared key's data. - */ - public - TSIG(Name algorithm, Name name, byte[] keyBytes) { - this.name = name; - this.alg = algorithm; - String macAlgorithm = nameToAlgorithm(algorithm); - SecretKey key = new SecretKeySpec(keyBytes, macAlgorithm); - init_hmac(macAlgorithm, key); - } - - /** - * Creates a new TSIG object, which can be used to sign or verify a message. - * - * @param name The name of the shared key. - * @param algorithm The algorithm of the shared key. The legal values are - * "hmac-md5", "hmac-sha1", "hmac-sha224", "hmac-sha256", "hmac-sha384", and - * "hmac-sha512". - * @param key The shared key's data represented as a base64 encoded string. - * - * @throws IllegalArgumentException The key name is an invalid name - * @throws IllegalArgumentException The key data is improperly encoded - */ - public - TSIG(String algorithm, String name, String key) { - this(algorithmToName(algorithm), name, key); - } - - /** - * Creates a new TSIG object, which can be used to sign or verify a message. - * - * @param name The name of the shared key. - * @param key The shared key's data represented as a base64 encoded string. - * - * @throws IllegalArgumentException The key name is an invalid name - * @throws IllegalArgumentException The key data is improperly encoded - */ - public - TSIG(Name algorithm, String name, String key) { - byte[] keyBytes; - try { - keyBytes = Base64Fast.decode2(key); - } catch (IOException e) { - throw new IllegalArgumentException("Invalid TSIG key string"); - } - - if (keyBytes == null) { - throw new IllegalArgumentException("Invalid TSIG key string"); - } - - try { - this.name = Name.fromString(name, Name.root); - } catch (TextParseException e) { - throw new IllegalArgumentException("Invalid TSIG key name"); - } - this.alg = algorithm; - String macAlgorithm = nameToAlgorithm(this.alg); - init_hmac(macAlgorithm, new SecretKeySpec(keyBytes, macAlgorithm)); - } - - /** - * Creates a new TSIG object with the hmac-md5 algorithm, which can be used to - * sign or verify a message. - * - * @param name The name of the shared key - * @param key The shared key's data, represented as a base64 encoded string. - * - * @throws IllegalArgumentException The key name is an invalid name - * @throws IllegalArgumentException The key data is improperly encoded - */ - public - TSIG(String name, String key) { - this(HMAC_MD5, name, key); - } - - /** - * Creates a new TSIG object, which can be used to sign or verify a message. - * - * @param str The TSIG key, in the form name:secret, name/secret, - * alg:name:secret, or alg/name/secret. If an algorithm is specified, it must - * be "hmac-md5", "hmac-sha1", or "hmac-sha256". - * - * @throws IllegalArgumentException The string does not contain both a name - * and secret. - * @throws IllegalArgumentException The key name is an invalid name - * @throws IllegalArgumentException The key data is improperly encoded - */ - static public - TSIG fromString(String str) { - String[] parts = str.split("[:/]", 3); - if (parts.length < 2) { - throw new IllegalArgumentException("Invalid TSIG key " + "specification"); - } - if (parts.length == 3) { - try { - return new TSIG(parts[0], parts[1], parts[2]); - } catch (IllegalArgumentException e) { - parts = str.split("[:/]", 2); - } - } - return new TSIG(HMAC_MD5, parts[0], parts[1]); - } - - /** - * Generates a TSIG record for a message and adds it to the message - * - * @param m The message - * @param old If this message is a response, the TSIG from the request - */ - public - void applyStream(DnsMessage m, TSIGRecord old, boolean first) { - if (first) { - apply(m, old); - return; - } - Date timeSigned = new Date(); - int fudge; - hmac.reset(); - - fudge = Options.intValue("tsigfudge"); - if (fudge < 0 || fudge > 0x7FFF) { - fudge = FUDGE; - } - - DnsOutput out = new DnsOutput(); - out.writeU16(old.getSignature().length); - hmac.update(out.toByteArray()); - hmac.update(old.getSignature()); - - /* Digest the message */ - hmac.update(m.toWire()); - - out = new DnsOutput(); - long time = timeSigned.getTime() / 1000; - int timeHigh = (int) (time >> 32); - long timeLow = (time & 0xFFFFFFFFL); - out.writeU16(timeHigh); - out.writeU32(timeLow); - out.writeU16(fudge); - - hmac.update(out.toByteArray()); - - byte[] signature = hmac.doFinal(); - byte[] other = null; - - DnsRecord r = new TSIGRecord(name, - DnsClass.ANY, - 0, - alg, - timeSigned, - fudge, - signature, - m.getHeader() - .getID(), - DnsResponseCode.NOERROR, - other); - m.addRecord(r, DnsSection.ADDITIONAL); - m.tsigState = DnsMessage.TSIG_SIGNED; - } - - /** - * Generates a TSIG record for a message and adds it to the message - * - * @param m The message - * @param old If this message is a response, the TSIG from the request - */ - public - void apply(DnsMessage m, TSIGRecord old) { - apply(m, DnsResponseCode.NOERROR, old); - } - - /** - * Generates a TSIG record with a specific error for a message and adds it - * to the message. - * - * @param m The message - * @param error The error - * @param old If this message is a response, the TSIG from the request - */ - public - void apply(DnsMessage m, int error, TSIGRecord old) { - DnsRecord r = generate(m, m.toWire(), error, old); - m.addRecord(r, DnsSection.ADDITIONAL); - m.tsigState = DnsMessage.TSIG_SIGNED; - } - - /** - * Generates a TSIG record with a specific error for a message that has - * been rendered. - * - * @param m The message - * @param b The rendered message - * @param error The error - * @param old If this message is a response, the TSIG from the request - * - * @return The TSIG record to be added to the message - */ - public - TSIGRecord generate(DnsMessage m, byte[] b, int error, TSIGRecord old) { - Date timeSigned; - if (error != DnsResponseCode.BADTIME) { - timeSigned = new Date(); - } - else { - timeSigned = old.getTimeSigned(); - } - int fudge; - boolean signing = false; - if (error == DnsResponseCode.NOERROR || error == DnsResponseCode.BADTIME) { - signing = true; - hmac.reset(); - } - - fudge = Options.intValue("tsigfudge"); - if (fudge < 0 || fudge > 0x7FFF) { - fudge = FUDGE; - } - - if (old != null) { - DnsOutput out = new DnsOutput(); - out.writeU16(old.getSignature().length); - if (signing) { - hmac.update(out.toByteArray()); - hmac.update(old.getSignature()); - } - } - - /* Digest the message */ - if (signing) { - hmac.update(b); - } - - DnsOutput out = new DnsOutput(); - name.toWireCanonical(out); - out.writeU16(DnsClass.ANY); /* class */ - out.writeU32(0); /* ttl */ - alg.toWireCanonical(out); - long time = timeSigned.getTime() / 1000; - int timeHigh = (int) (time >> 32); - long timeLow = (time & 0xFFFFFFFFL); - out.writeU16(timeHigh); - out.writeU32(timeLow); - out.writeU16(fudge); - - out.writeU16(error); - out.writeU16(0); /* No other data */ - - if (signing) { - hmac.update(out.toByteArray()); - } - - byte[] signature; - if (signing) { - signature = hmac.doFinal(); - } - else { - signature = new byte[0]; - } - - byte[] other = null; - if (error == DnsResponseCode.BADTIME) { - out = new DnsOutput(); - time = new Date().getTime() / 1000; - timeHigh = (int) (time >> 32); - timeLow = (time & 0xFFFFFFFFL); - out.writeU16(timeHigh); - out.writeU32(timeLow); - other = out.toByteArray(); - } - - return (new TSIGRecord(name, - DnsClass.ANY, - 0, - alg, - timeSigned, - fudge, - signature, - m.getHeader() - .getID(), - error, - other)); - } - - /** - * Verifies a TSIG record on an incoming message. Since this is only called - * in the context where a TSIG is expected to be present, it is an error - * if one is not present. After calling this routine, DnsMessage.isVerified() may - * be called on this message. - * - * @param m The message - * @param b The message in unparsed form. This is necessary since TSIG - * signs the message in wire format, and we can't recreate the exact wire - * format (with the same name compression). - * @param old If this message is a response, the TSIG from the request - * - * @return The result of the verification (as an DnsResponseCode) - * - * @see DnsResponseCode - */ - public - int verify(DnsMessage m, byte[] b, TSIGRecord old) { - return verify(m, b, b.length, old); - } - - /** - * Verifies a TSIG record on an incoming message. Since this is only called - * in the context where a TSIG is expected to be present, it is an error - * if one is not present. After calling this routine, DnsMessage.isVerified() may - * be called on this message. - * - * @param m The message - * @param b An array containing the message in unparsed form. This is - * necessary since TSIG signs the message in wire format, and we can't - * recreate the exact wire format (with the same name compression). - * @param length The length of the message in the array. - * @param old If this message is a response, the TSIG from the request - * - * @return The result of the verification (as an DnsResponseCode) - * - * @see DnsResponseCode - */ - public - byte verify(DnsMessage m, byte[] b, int length, TSIGRecord old) { - m.tsigState = DnsMessage.TSIG_FAILED; - TSIGRecord tsig = m.getTSIG(); - hmac.reset(); - if (tsig == null) { - return DnsResponseCode.FORMERR; - } - - if (!tsig.getName() - .equals(name) || !tsig.getAlgorithm() - .equals(alg)) { - if (Options.check("verbose")) { - System.err.println("BADKEY failure"); - } - return DnsResponseCode.BADKEY; - } - long now = System.currentTimeMillis(); - long then = tsig.getTimeSigned() - .getTime(); - long fudge = tsig.getFudge(); - if (Math.abs(now - then) > fudge * 1000) { - if (Options.check("verbose")) { - System.err.println("BADTIME failure"); - } - return DnsResponseCode.BADTIME; - } - - if (old != null && tsig.getError() != DnsResponseCode.BADKEY && tsig.getError() != DnsResponseCode.BADSIG) { - DnsOutput out = new DnsOutput(); - out.writeU16(old.getSignature().length); - hmac.update(out.toByteArray()); - hmac.update(old.getSignature()); - } - m.getHeader() - .decCount(DnsSection.ADDITIONAL); - byte[] header = m.getHeader() - .toWire(); - m.getHeader() - .incCount(DnsSection.ADDITIONAL); - hmac.update(header); - - int len = m.tsigstart - header.length; - hmac.update(b, header.length, len); - - DnsOutput out = new DnsOutput(); - tsig.getName() - .toWireCanonical(out); - out.writeU16(tsig.dclass); - out.writeU32(tsig.ttl); - tsig.getAlgorithm() - .toWireCanonical(out); - long time = tsig.getTimeSigned() - .getTime() / 1000; - int timeHigh = (int) (time >> 32); - long timeLow = (time & 0xFFFFFFFFL); - out.writeU16(timeHigh); - out.writeU32(timeLow); - out.writeU16(tsig.getFudge()); - out.writeU16(tsig.getError()); - if (tsig.getOther() != null) { - out.writeU16(tsig.getOther().length); - out.writeByteArray(tsig.getOther()); - } - else { - out.writeU16(0); - } - - hmac.update(out.toByteArray()); - - byte[] signature = tsig.getSignature(); - int digestLength = hmac.getMacLength(); - int minDigestLength; - if (hmac.getAlgorithm() - .toLowerCase() - .contains("md5")) { - minDigestLength = 10; - } - else { - minDigestLength = digestLength / 2; - } - - if (signature.length > digestLength) { - if (Options.check("verbose")) { - System.err.println("BADSIG: signature too long"); - } - return DnsResponseCode.BADSIG; - } - else if (signature.length < minDigestLength) { - if (Options.check("verbose")) { - System.err.println("BADSIG: signature too short"); - } - return DnsResponseCode.BADSIG; - } - else if (!verify(hmac, signature, true)) { - if (Options.check("verbose")) { - System.err.println("BADSIG: signature verification"); - } - return DnsResponseCode.BADSIG; - } - - m.tsigState = DnsMessage.TSIG_VERIFIED; - return DnsResponseCode.NOERROR; - } - - /** - * Returns the maximum length of a TSIG record generated by this key. - * - * @see TSIGRecord - */ - public - int recordLength() { - return (name.length() + 10 + alg.length() + 8 + // time signed, fudge - 18 + // 2 byte MAC length, 16 byte MAC - 4 + // original id, error - 8); // 2 byte error length, 6 byte max error field. - } - - public static - class StreamVerifier { - /** - * A helper class for verifying multiple message responses. - */ - - private TSIG key; - private Mac verifier; - private int nresponses; - private int lastsigned; - private TSIGRecord lastTSIG; - - /** - * Creates an object to verify a multiple message response - */ - public - StreamVerifier(TSIG tsig, TSIGRecord old) { - key = tsig; - verifier = tsig.hmac; - nresponses = 0; - lastTSIG = old; - } - - /** - * Verifies a TSIG record on an incoming message that is part of a - * multiple message response. - * TSIG records must be present on the first and last messages, and - * at least every 100 records in between. - * After calling this routine, DnsMessage.isVerified() may be called on - * this message. - * - * @param m The message - * @param b The message in unparsed form - * - * @return The result of the verification (as an DnsResponseCode) - * - * @see DnsResponseCode - */ - public - int verify(DnsMessage m, byte[] b) { - TSIGRecord tsig = m.getTSIG(); - - nresponses++; - - if (nresponses == 1) { - int result = key.verify(m, b, lastTSIG); - if (result == DnsResponseCode.NOERROR) { - byte[] signature = tsig.getSignature(); - DnsOutput out = new DnsOutput(); - out.writeU16(signature.length); - verifier.update(out.toByteArray()); - verifier.update(signature); - } - lastTSIG = tsig; - return result; - } - - if (tsig != null) { - m.getHeader() - .decCount(DnsSection.ADDITIONAL); - } - byte[] header = m.getHeader() - .toWire(); - if (tsig != null) { - m.getHeader() - .incCount(DnsSection.ADDITIONAL); - } - verifier.update(header); - - int len; - if (tsig == null) { - len = b.length - header.length; - } - else { - len = m.tsigstart - header.length; - } - verifier.update(b, header.length, len); - - if (tsig != null) { - lastsigned = nresponses; - lastTSIG = tsig; - } - else { - boolean required = (nresponses - lastsigned >= 100); - if (required) { - m.tsigState = DnsMessage.TSIG_FAILED; - return DnsResponseCode.FORMERR; - } - else { - m.tsigState = DnsMessage.TSIG_INTERMEDIATE; - return DnsResponseCode.NOERROR; - } - } - - if (!tsig.getName() - .equals(key.name) || !tsig.getAlgorithm() - .equals(key.alg)) { - if (Options.check("verbose")) { - System.err.println("BADKEY failure"); - } - m.tsigState = DnsMessage.TSIG_FAILED; - return DnsResponseCode.BADKEY; - } - - DnsOutput out = new DnsOutput(); - long time = tsig.getTimeSigned() - .getTime() / 1000; - int timeHigh = (int) (time >> 32); - long timeLow = (time & 0xFFFFFFFFL); - out.writeU16(timeHigh); - out.writeU32(timeLow); - out.writeU16(tsig.getFudge()); - verifier.update(out.toByteArray()); - - if (TSIG.verify(verifier, tsig.getSignature()) == false) { - if (Options.check("verbose")) { - System.err.println("BADSIG failure"); - } - m.tsigState = DnsMessage.TSIG_FAILED; - return DnsResponseCode.BADSIG; - } - - verifier.reset(); - out = new DnsOutput(); - out.writeU16(tsig.getSignature().length); - verifier.update(out.toByteArray()); - verifier.update(tsig.getSignature()); - - m.tsigState = DnsMessage.TSIG_VERIFIED; - return DnsResponseCode.NOERROR; - } - } - -} diff --git a/src/dorkbox/network/dns/records/TSIGRecord.java b/src/dorkbox/network/dns/records/TSIGRecord.java deleted file mode 100644 index f47984b5..00000000 --- a/src/dorkbox/network/dns/records/TSIGRecord.java +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.util.Date; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.utils.Options; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.util.Base64Fast; -import dorkbox.util.OS; - -/** - * Transaction Signature - this record is automatically generated by the - * resolver. TSIG records provide transaction security between the - * sender and receiver of a message, using a shared key. - * - * @author Brian Wellington - * @see TSIG - */ - -public -class TSIGRecord extends DnsRecord { - - private static final long serialVersionUID = -88820909016649306L; - - private Name alg; - private Date timeSigned; - private int fudge; - private byte[] signature; - private int originalID; - private int error; - private byte[] other; - - TSIGRecord() {} - - @Override - DnsRecord getObject() { - return new TSIGRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - alg = new Name(in); - - long timeHigh = in.readU16(); - long timeLow = in.readU32(); - long time = (timeHigh << 32) + timeLow; - timeSigned = new Date(time * 1000); - fudge = in.readU16(); - - int sigLen = in.readU16(); - signature = in.readByteArray(sigLen); - - originalID = in.readU16(); - error = in.readU16(); - - int otherLen = in.readU16(); - if (otherLen > 0) { - other = in.readByteArray(otherLen); - } - else { - other = null; - } - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - alg.toWire(out, null, canonical); - - long time = timeSigned.getTime() / 1000; - int timeHigh = (int) (time >> 32); - long timeLow = (time & 0xFFFFFFFFL); - out.writeU16(timeHigh); - out.writeU32(timeLow); - out.writeU16(fudge); - - out.writeU16(signature.length); - out.writeByteArray(signature); - - out.writeU16(originalID); - out.writeU16(error); - - if (other != null) { - out.writeU16(other.length); - out.writeByteArray(other); - } - else { - out.writeU16(0); - } - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(alg); - sb.append(" "); - if (Options.check("multiline")) { - sb.append("(") - .append(OS.LINE_SEPARATOR) - .append("\t"); - } - - sb.append(timeSigned.getTime() / 1000); - sb.append(" "); - sb.append(fudge); - sb.append(" "); - sb.append(signature.length); - if (Options.check("multiline")) { - sb.append(OS.LINE_SEPARATOR); - sb.append(Base64Fast.formatString(Base64Fast.encode2(signature), 64, "\t", true)); - } - else { - sb.append(" "); - sb.append(Base64Fast.encode2(signature)); - } - sb.append(" "); - sb.append(DnsResponseCode.TSIGstring(error)); - sb.append(" "); - if (other == null) { - sb.append(0); - } - else { - sb.append(other.length); - if (Options.check("multiline")) { - sb.append(OS.LINE_SEPARATOR) - .append(OS.LINE_SEPARATOR) - .append(OS.LINE_SEPARATOR) - .append("\t"); - } - else { - sb.append(" "); - } - if (error == DnsResponseCode.BADTIME) { - if (other.length != 6) { - sb.append(""); - } - else { - long time = ((long) (other[0] & 0xFF) << 40) + ((long) (other[1] & 0xFF) << 32) + ((other[2] & 0xFF) << 24) + - ((other[3] & 0xFF) << 16) + ((other[4] & 0xFF) << 8) + ((other[5] & 0xFF)); - sb.append(""); - } - } - else { - sb.append("<"); - sb.append(Base64Fast.encode2(other)); - sb.append(">"); - } - } - if (Options.check("multiline")) { - sb.append(" )"); - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - throw st.exception("no text format defined for TSIG"); - } - - /** - * Creates a TSIG Record from the given data. This is normally called by - * the TSIG class - * - * @param alg The shared key's algorithm - * @param timeSigned The time that this record was generated - * @param fudge The fudge factor for time - if the time that the message is - * received is not in the range [now - fudge, now + fudge], the signature - * fails - * @param signature The signature - * @param originalID The message ID at the time of its generation - * @param error The extended error field. Should be 0 in queries. - * @param other The other data field. Currently used only in BADTIME - * responses. - * - * @see TSIG - */ - public - TSIGRecord(Name name, - int dclass, - long ttl, - Name alg, - Date timeSigned, - int fudge, - byte[] signature, - int originalID, - int error, - byte other[]) { - super(name, DnsRecordType.TSIG, dclass, ttl); - this.alg = checkName("alg", alg); - this.timeSigned = timeSigned; - this.fudge = checkU16("fudge", fudge); - this.signature = signature; - this.originalID = checkU16("originalID", originalID); - this.error = checkU16("error", error); - this.other = other; - } - - /** - * Returns the shared key's algorithm - */ - public - Name getAlgorithm() { - return alg; - } - - /** - * Returns the time that this record was generated - */ - public - Date getTimeSigned() { - return timeSigned; - } - - /** - * Returns the time fudge factor - */ - public - int getFudge() { - return fudge; - } - - /** - * Returns the signature - */ - public - byte[] getSignature() { - return signature; - } - - /** - * Returns the original message ID - */ - public - int getOriginalID() { - return originalID; - } - - /** - * Returns the extended error - */ - public - int getError() { - return error; - } - - /** - * Returns the other data - */ - public - byte[] getOther() { - return other; - } - -} diff --git a/src/dorkbox/network/dns/records/TTL.java b/src/dorkbox/network/dns/records/TTL.java deleted file mode 100644 index 1deb2c2b..00000000 --- a/src/dorkbox/network/dns/records/TTL.java +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import dorkbox.network.dns.exceptions.InvalidTTLException; - -/** - * Routines for parsing BIND-style TTL values. These values consist of - * numbers followed by 1 letter units of time (W - week, D - day, H - hour, - * M - minute, S - second). - * - * @author Brian Wellington - */ - -public final -class TTL { - - public static final long MAX_VALUE = 0x7FFFFFFFL; - - private - TTL() {} - - /** - * Parses a TTL, which can either be expressed as a number or a BIND-style - * string with numbers and units. - * - * @param s The string representing the TTL - * - * @return The TTL as a number of seconds - * - * @throws NumberFormatException The string was not in a valid TTL format. - */ - public static - long parseTTL(String s) { - return parse(s, true); - } - - /** - * Parses a TTL-like value, which can either be expressed as a number or a - * BIND-style string with numbers and units. - * - * @param s The string representing the numeric value. - * @param clamp Whether to clamp values in the range [MAX_VALUE + 1, 2^32 -1] - * to MAX_VALUE. This should be donw for TTLs, but not other values which - * can be expressed in this format. - * - * @return The value as a number of seconds - * - * @throws NumberFormatException The string was not in a valid TTL format. - */ - public static - long parse(String s, boolean clamp) { - if (s == null || s.length() == 0 || !Character.isDigit(s.charAt(0))) { - throw new NumberFormatException(); - } - long value = 0; - long ttl = 0; - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - long oldvalue = value; - if (Character.isDigit(c)) { - value = (value * 10) + Character.getNumericValue(c); - if (value < oldvalue) { - throw new NumberFormatException(); - } - } - else { - switch (Character.toUpperCase(c)) { - case 'W': - value *= 7; - case 'D': - value *= 24; - case 'H': - value *= 60; - case 'M': - value *= 60; - case 'S': - break; - default: - throw new NumberFormatException(); - } - ttl += value; - value = 0; - if (ttl > 0xFFFFFFFFL) { - throw new NumberFormatException(); - } - } - } - if (ttl == 0) { - ttl = value; - } - - if (ttl > 0xFFFFFFFFL) { - throw new NumberFormatException(); - } - else if (ttl > MAX_VALUE && clamp) { - ttl = MAX_VALUE; - } - return ttl; - } - - public static - String format(long ttl) { - TTL.check(ttl); - StringBuilder sb = new StringBuilder(); - long secs, mins, hours, days, weeks; - secs = ttl % 60; - ttl /= 60; - mins = ttl % 60; - ttl /= 60; - hours = ttl % 24; - ttl /= 24; - days = ttl % 7; - ttl /= 7; - weeks = ttl; - if (weeks > 0) { - sb.append(weeks) - .append("W"); - } - if (days > 0) { - sb.append(days) - .append("D"); - } - if (hours > 0) { - sb.append(hours) - .append("H"); - } - if (mins > 0) { - sb.append(mins) - .append("M"); - } - if (secs > 0 || (weeks == 0 && days == 0 && hours == 0 && mins == 0)) { - sb.append(secs) - .append("S"); - } - return sb.toString(); - } - - static - void check(long i) { - if (i < 0 || i > MAX_VALUE) { - throw new InvalidTTLException(i); - } - } - -} diff --git a/src/dorkbox/network/dns/records/TXTBase.java b/src/dorkbox/network/dns/records/TXTBase.java deleted file mode 100644 index d09f4783..00000000 --- a/src/dorkbox/network/dns/records/TXTBase.java +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Implements common functionality for the many record types whose format - * is a list of strings. - * - * @author Brian Wellington - */ - -abstract -class TXTBase extends DnsRecord { - - private static final long serialVersionUID = -4319510507246305931L; - - protected List strings; - - protected - TXTBase() {} - - protected - TXTBase(Name name, int type, int dclass, long ttl) { - super(name, type, dclass, ttl); - } - - protected - TXTBase(Name name, int type, int dclass, long ttl, String string) { - this(name, type, dclass, ttl, Collections.singletonList(string)); - } - - protected - TXTBase(Name name, int type, int dclass, long ttl, List strings) { - super(name, type, dclass, ttl); - if (strings == null) { - throw new IllegalArgumentException("strings must not be null"); - } - this.strings = new ArrayList(strings.size()); - Iterator it = strings.iterator(); - try { - while (it.hasNext()) { - String s = (String) it.next(); - this.strings.add(byteArrayFromString(s)); - } - } catch (TextParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - strings = new ArrayList(2); - while (in.remaining() > 0) { - byte[] b = in.readCountedString(); - strings.add(b); - } - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - Iterator it = strings.iterator(); - while (it.hasNext()) { - byte[] b = (byte[]) it.next(); - out.writeCountedString(b); - } - } - - /** - * converts to a String - */ - @Override - void rrToString(StringBuilder sb) { - Iterator it = strings.iterator(); - while (it.hasNext()) { - byte[] array = (byte[]) it.next(); - sb.append(byteArrayToString(array, true)); - if (it.hasNext()) { - sb.append(" "); - } - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - strings = new ArrayList(2); - while (true) { - Tokenizer.Token t = st.get(); - if (!t.isString()) { - break; - } - try { - strings.add(byteArrayFromString(t.value)); - } catch (TextParseException e) { - throw st.exception(e.getMessage()); - } - - } - st.unget(); - } - - /** - * Returns the text strings - * - * @return A list of Strings corresponding to the text strings. - */ - public - List getStrings() { - List list = new ArrayList(strings.size()); - for (int i = 0; i < strings.size(); i++) { - list.add(byteArrayToString((byte[]) strings.get(i), false)); - } - return list; - } - - /** - * Returns the text strings - * - * @return A list of byte arrays corresponding to the text strings. - */ - public - List getStringsAsByteArrays() { - return strings; - } - -} diff --git a/src/dorkbox/network/dns/records/TXTRecord.java b/src/dorkbox/network/dns/records/TXTRecord.java deleted file mode 100644 index ad92aeea..00000000 --- a/src/dorkbox/network/dns/records/TXTRecord.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.util.List; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; - -/** - * Text - stores text strings - * - * @author Brian Wellington - */ - -public -class TXTRecord extends TXTBase { - - private static final long serialVersionUID = -5780785764284221342L; - - TXTRecord() {} - - @Override - DnsRecord getObject() { - return new TXTRecord(); - } - - /** - * Creates a TXT Record from the given data - * - * @param strings The text strings - * - * @throws IllegalArgumentException One of the strings has invalid escapes - */ - public - TXTRecord(Name name, int dclass, long ttl, List strings) { - super(name, DnsRecordType.TXT, dclass, ttl, strings); - } - - /** - * Creates a TXT Record from the given data - * - * @param string One text string - * - * @throws IllegalArgumentException The string has invalid escapes - */ - public - TXTRecord(Name name, int dclass, long ttl, String string) { - super(name, DnsRecordType.TXT, dclass, ttl, string); - } - -} diff --git a/src/dorkbox/network/dns/records/TypeBitmap.java b/src/dorkbox/network/dns/records/TypeBitmap.java deleted file mode 100644 index 782fb6b3..00000000 --- a/src/dorkbox/network/dns/records/TypeBitmap.java +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (c) 2004-2009 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -/** - * Routines for deal with the lists of types found in NSEC/NSEC3 records. - * - * @author Brian Wellington - */ - -import java.io.IOException; -import java.io.Serializable; -import java.util.Iterator; -import java.util.TreeSet; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.util.collections.IntMap; -import dorkbox.util.collections.IntMap.Keys; - -final -class TypeBitmap implements Serializable { - - private static final long serialVersionUID = -125354057735389003L; - - private IntMap types; - - public - TypeBitmap(int[] array) { - this(); - for (int i = 0; i < array.length; i++) { - DnsRecordType.check(array[i]); - types.put(array[i], Boolean.TRUE); - } - } - - private - TypeBitmap() { - types = new IntMap(); - } - - public - TypeBitmap(DnsInput in) throws WireParseException { - this(); - int lastbase = -1; - - while (in.remaining() > 0) { - if (in.remaining() < 2) { - throw new WireParseException("invalid bitmap descriptor"); - } - - int mapbase = in.readU8(); - if (mapbase < lastbase) { - throw new WireParseException("invalid ordering"); - } - - int maplength = in.readU8(); - if (maplength > in.remaining()) { - throw new WireParseException("invalid bitmap"); - } - - for (int i = 0; i < maplength; i++) { - int current = in.readU8(); - if (current == 0) { - continue; - } - - for (int j = 0; j < 8; j++) { - if ((current & (1 << (7 - j))) == 0) { - continue; - } - - int typecode = mapbase * 256 + +i * 8 + j; - types.put(typecode, Boolean.TRUE); - } - } - } - } - - public - TypeBitmap(Tokenizer st) throws IOException { - this(); - - while (true) { - Tokenizer.Token t = st.get(); - if (!t.isString()) { - break; - } - - int typecode = DnsRecordType.value(t.value); - if (typecode < 0) { - throw st.exception("Invalid type: " + t.value); - } - - types.put(typecode, Boolean.TRUE); - } - st.unget(); - } - - public - int[] toArray() { - int[] array = new int[types.size]; - int n = 0; - - - Keys keys = types.keys(); - while (keys.hasNext) { - array[n++] = keys.next(); - } - - return array; - } - - @Override - public - String toString() { - StringBuilder sb = new StringBuilder(); - - Keys keys = types.keys(); - while (keys.hasNext) { - int t = keys.next(); - sb.append(DnsRecordType.string(t)) - .append(' '); - } - - // remove the last ' ' - int length = sb.length(); - if (length > 1) { - sb.delete(length - 1, length); - } - - return sb.toString(); - } - - public - void toWire(DnsOutput out) { - if (types.size == 0) { - return; - } - - int mapbase = -1; - TreeSet map = new TreeSet(); - - Keys keys = types.keys(); - while (keys.hasNext) { - int t = keys.next(); - - int base = t >> 8; - if (base != mapbase) { - if (map.size() > 0) { - mapToWire(out, map, mapbase); - map.clear(); - } - mapbase = base; - } - map.add(new Integer(t)); - } - - mapToWire(out, map, mapbase); - } - - /** - * @param map this must be an ordered data structure! - */ - private static - void mapToWire(DnsOutput out, TreeSet map, int mapbase) { - int arraymax = (((Integer) map.last()).intValue()) & 0xFF; - int arraylength = (arraymax / 8) + 1; - int[] array = new int[arraylength]; - - out.writeU8(mapbase); - out.writeU8(arraylength); - - for (Iterator it = map.iterator(); it.hasNext(); ) { - int typecode = ((Integer) it.next()).intValue(); - array[(typecode & 0xFF) / 8] |= (1 << (7 - typecode % 8)); - } - - for (int j = 0; j < arraylength; j++) { - out.writeU8(array[j]); - } - } - - public - boolean empty() { - return types.size == 0; - } - - public - boolean contains(int typecode) { - return types.containsKey(typecode); - } -} diff --git a/src/dorkbox/network/dns/records/U16NameBase.java b/src/dorkbox/network/dns/records/U16NameBase.java deleted file mode 100644 index 1e080b4e..00000000 --- a/src/dorkbox/network/dns/records/U16NameBase.java +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Implements common functionality for the many record types whose format - * is an unsigned 16 bit integer followed by a name. - * - * @author Brian Wellington - */ - -abstract -class U16NameBase extends DnsRecord { - - private static final long serialVersionUID = -8315884183112502995L; - - protected int u16Field; - protected Name nameField; - - protected - U16NameBase() {} - - protected - U16NameBase(Name name, int type, int dclass, long ttl) { - super(name, type, dclass, ttl); - } - - protected - U16NameBase(Name name, int type, int dclass, long ttl, int u16Field, String u16Description, Name nameField, String nameDescription) { - super(name, type, dclass, ttl); - this.u16Field = checkU16(u16Description, u16Field); - this.nameField = checkName(nameDescription, nameField); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - u16Field = in.readU16(); - nameField = new Name(in); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU16(u16Field); - nameField.toWire(out, null, canonical); - } - - @Override - void rrToString(StringBuilder sb) { - sb.append(u16Field); - sb.append(" "); - sb.append(nameField); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - u16Field = st.getUInt16(); - nameField = st.getName(origin); - } - - protected - int getU16Field() { - return u16Field; - } - - protected - Name getNameField() { - return nameField; - } - -} diff --git a/src/dorkbox/network/dns/records/UNKRecord.java b/src/dorkbox/network/dns/records/UNKRecord.java deleted file mode 100644 index a9d2a7ac..00000000 --- a/src/dorkbox/network/dns/records/UNKRecord.java +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * A class implementing Records of unknown and/or unimplemented types. This - * class can only be initialized using static Record initializers. - * - * @author Brian Wellington - */ - -public -class UNKRecord extends DnsRecord { - - private static final long serialVersionUID = -4193583311594626915L; - - private byte[] data; - - UNKRecord() {} - - @Override - DnsRecord getObject() { - return new UNKRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - data = in.readByteArray(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeByteArray(data); - } - - /** - * Converts this Record to the String "unknown format" - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(unknownToString(data)); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - throw st.exception("invalid unknown RR encoding"); - } - - /** - * Returns the contents of this record. - */ - public - byte[] getData() { - return data; - } - -} diff --git a/src/dorkbox/network/dns/records/URIRecord.java b/src/dorkbox/network/dns/records/URIRecord.java deleted file mode 100644 index 27d47820..00000000 --- a/src/dorkbox/network/dns/records/URIRecord.java +++ /dev/null @@ -1,120 +0,0 @@ -// Implemented by Anthony Kirby (anthony@anthony.org) -// based on SRVRecord.java Copyright (c) 1999-2004 Brian Wellington - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Uniform Resource Identifier (URI) DNS Resource Record - * - * @author Anthony Kirby - * @see http://tools.ietf.org/html/draft-faltstrom-uri - */ - -public -class URIRecord extends DnsRecord { - - private static final long serialVersionUID = 7955422413971804232L; - - private int priority, weight; - private byte[] target; - - URIRecord() { - target = new byte[] {}; - } - - @Override - DnsRecord getObject() { - return new URIRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - priority = in.readU16(); - weight = in.readU16(); - target = in.readByteArray(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeU16(priority); - out.writeU16(weight); - out.writeByteArray(target); - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(priority + " "); - sb.append(weight + " "); - sb.append(byteArrayToString(target, true)); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - priority = st.getUInt16(); - weight = st.getUInt16(); - try { - target = byteArrayFromString(st.getString()); - } catch (TextParseException e) { - throw st.exception(e.getMessage()); - } - } - - /** - * Creates a URI Record from the given data - * - * @param priority The priority of this URI. Records with lower priority - * are preferred. - * @param weight The weight, used to select between records at the same - * priority. - * @param target The host/port running the service - */ - public - URIRecord(Name name, int dclass, long ttl, int priority, int weight, String target) { - super(name, DnsRecordType.URI, dclass, ttl); - this.priority = checkU16("priority", priority); - this.weight = checkU16("weight", weight); - try { - this.target = byteArrayFromString(target); - } catch (TextParseException e) { - throw new IllegalArgumentException(e.getMessage()); - } - } - - /** - * Returns the priority - */ - public - int getPriority() { - return priority; - } - - /** - * Returns the weight - */ - public - int getWeight() { - return weight; - } - - /** - * Returns the target URI - */ - public - String getTarget() { - return byteArrayToString(target, false); - } - -} diff --git a/src/dorkbox/network/dns/records/Update.java b/src/dorkbox/network/dns/records/Update.java deleted file mode 100644 index 6da3d06c..00000000 --- a/src/dorkbox/network/dns/records/Update.java +++ /dev/null @@ -1,322 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.util.Iterator; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsOpCode; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.exceptions.RelativeNameException; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * A helper class for constructing dynamic DNS (DDNS) update messages. - * - * @author Brian Wellington - */ - -public -class Update extends DnsMessage { - - private Name origin; - private int dclass; - - /** - * Creates an update message. The class is assumed to be IN. - * - * @param zone The name of the zone being updated. - */ - public - Update(Name zone) { - this(zone, DnsClass.IN); - } - - /** - * Creates an update message. - * - * @param zone The name of the zone being updated. - * @param dclass The class of the zone being updated. - */ - public - Update(Name zone, int dclass) { - super(); - if (!zone.isAbsolute()) { - throw new RelativeNameException(zone); - } - DnsClass.check(dclass); - getHeader().setOpcode(DnsOpCode.UPDATE); - DnsRecord soa = DnsRecord.newRecord(zone, DnsRecordType.SOA, DnsClass.IN); - addRecord(soa, DnsSection.QUESTION); - this.origin = zone; - this.dclass = dclass; - } - - /** - * Inserts a prerequisite that the specified name exists; that is, there - * exist records with the given name in the zone. - */ - public - void present(Name name) { - newPrereq(DnsRecord.newRecord(name, DnsRecordType.ANY, DnsClass.ANY, 0)); - } - - private - void newPrereq(DnsRecord rec) { - addRecord(rec, DnsSection.PREREQ); - } - - /** - * Inserts a prerequisite that the specified rrset exists; that is, there - * exist records with the given name and type in the zone. - */ - public - void present(Name name, int type) { - newPrereq(DnsRecord.newRecord(name, type, DnsClass.ANY, 0)); - } - - /** - * Parses a record from the string, and inserts a prerequisite that the - * record exists. Due to the way value-dependent prequisites work, the - * condition that must be met is that the set of all records with the same - * and type in the update message must be identical to the set of all records - * with that name and type on the server. - * - * @throws IOException The record could not be parsed. - */ - public - void present(Name name, int type, String record) throws IOException { - newPrereq(DnsRecord.fromString(name, type, dclass, 0, record, origin)); - } - - /** - * Parses a record from the tokenizer, and inserts a prerequisite that the - * record exists. Due to the way value-dependent prequisites work, the - * condition that must be met is that the set of all records with the same - * and type in the update message must be identical to the set of all records - * with that name and type on the server. - * - * @throws IOException The record could not be parsed. - */ - public - void present(Name name, int type, Tokenizer tokenizer) throws IOException { - newPrereq(DnsRecord.fromString(name, type, dclass, 0, tokenizer, origin)); - } - - /** - * Inserts a prerequisite that the specified record exists. Due to the way - * value-dependent prequisites work, the condition that must be met is that - * the set of all records with the same and type in the update message must - * be identical to the set of all records with that name and type on the server. - */ - public - void present(DnsRecord record) { - newPrereq(record); - } - - /** - * Inserts a prerequisite that the specified name does not exist; that is, - * there are no records with the given name in the zone. - */ - public - void absent(Name name) { - newPrereq(DnsRecord.newRecord(name, DnsRecordType.ANY, DnsClass.NONE, 0)); - } - - /** - * Inserts a prerequisite that the specified rrset does not exist; that is, - * there are no records with the given name and type in the zone. - */ - public - void absent(Name name, int type) { - newPrereq(DnsRecord.newRecord(name, type, DnsClass.NONE, 0)); - } - - /** - * Indicates that the records should be inserted into the zone. - */ - public - void add(DnsRecord[] records) { - for (int i = 0; i < records.length; i++) { - add(records[i]); - } - } - - /** - * Indicates that the record should be inserted into the zone. - */ - public - void add(DnsRecord record) { - newUpdate(record); - } - - private - void newUpdate(DnsRecord rec) { - addRecord(rec, DnsSection.UPDATE); - } - - /** - * Indicates that all of the records in the rrset should be inserted into the - * zone. - */ - public - void add(RRset rrset) { - for (Iterator it = rrset.rrs(); it.hasNext(); ) { - add((DnsRecord) it.next()); - } - } - - /** - * Indicates that all records with the given name should be deleted from - * the zone. - */ - public - void delete(Name name) { - newUpdate(DnsRecord.newRecord(name, DnsRecordType.ANY, DnsClass.ANY, 0)); - } - - /** - * Parses a record from the string, and indicates that the record - * should be deleted from the zone. - * - * @throws IOException The record could not be parsed. - */ - public - void delete(Name name, int type, String record) throws IOException { - newUpdate(DnsRecord.fromString(name, type, DnsClass.NONE, 0, record, origin)); - } - - /** - * Parses a record from the tokenizer, and indicates that the record - * should be deleted from the zone. - * - * @throws IOException The record could not be parsed. - */ - public - void delete(Name name, int type, Tokenizer tokenizer) throws IOException { - newUpdate(DnsRecord.fromString(name, type, DnsClass.NONE, 0, tokenizer, origin)); - } - - /** - * Indicates that the records should be deleted from the zone. - */ - public - void delete(DnsRecord[] records) { - for (int i = 0; i < records.length; i++) { - delete(records[i]); - } - } - - /** - * Indicates that the specified record should be deleted from the zone. - */ - public - void delete(DnsRecord record) { - newUpdate(record.withDClass(DnsClass.NONE, 0)); - } - - /** - * Indicates that all of the records in the rrset should be deleted from the - * zone. - */ - public - void delete(RRset rrset) { - for (Iterator it = rrset.rrs(); it.hasNext(); ) { - delete((DnsRecord) it.next()); - } - } - - /** - * Parses a record from the string, and indicates that the record - * should be inserted into the zone replacing any other records with the - * same name and type. - * - * @throws IOException The record could not be parsed. - */ - public - void replace(Name name, int type, long ttl, String record) throws IOException { - delete(name, type); - add(name, type, ttl, record); - } - - /** - * Parses a record from the string, and indicates that the record - * should be inserted into the zone. - * - * @throws IOException The record could not be parsed. - */ - public - void add(Name name, int type, long ttl, String record) throws IOException { - newUpdate(DnsRecord.fromString(name, type, dclass, ttl, record, origin)); - } - - /** - * Indicates that all records with the given name and type should be deleted - * from the zone. - */ - public - void delete(Name name, int type) { - newUpdate(DnsRecord.newRecord(name, type, DnsClass.ANY, 0)); - } - - /** - * Parses a record from the tokenizer, and indicates that the record - * should be inserted into the zone replacing any other records with the - * same name and type. - * - * @throws IOException The record could not be parsed. - */ - public - void replace(Name name, int type, long ttl, Tokenizer tokenizer) throws IOException { - delete(name, type); - add(name, type, ttl, tokenizer); - } - - /** - * Parses a record from the tokenizer, and indicates that the record - * should be inserted into the zone. - * - * @throws IOException The record could not be parsed. - */ - public - void add(Name name, int type, long ttl, Tokenizer tokenizer) throws IOException { - newUpdate(DnsRecord.fromString(name, type, dclass, ttl, tokenizer, origin)); - } - - /** - * Indicates that the records should be inserted into the zone replacing any - * other records with the same name and type as each one. - */ - public - void replace(DnsRecord[] records) { - for (int i = 0; i < records.length; i++) { - replace(records[i]); - } - } - - /** - * Indicates that the record should be inserted into the zone replacing any - * other records with the same name and type. - */ - public - void replace(DnsRecord record) { - delete(record.getName(), record.getType()); - add(record); - } - - /** - * Indicates that all of the records in the rrset should be inserted into the - * zone replacing any other records with the same name and type. - */ - public - void replace(RRset rrset) { - delete(rrset.getName(), rrset.getType()); - for (Iterator it = rrset.rrs(); it.hasNext(); ) { - add((DnsRecord) it.next()); - } - } - -} diff --git a/src/dorkbox/network/dns/records/WKSRecord.java b/src/dorkbox/network/dns/records/WKSRecord.java deleted file mode 100644 index 3e6a862c..00000000 --- a/src/dorkbox/network/dns/records/WKSRecord.java +++ /dev/null @@ -1,861 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Mnemonic; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Address; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * Well Known Services - Lists services offered by this host. - * - * @author Brian Wellington - */ - -public -class WKSRecord extends DnsRecord { - - private static final long serialVersionUID = -9104259763909119805L; - private byte[] address; - private int protocol; - private int[] services; - - - public static - class Protocol { - /** - * Internet Control DnsMessage - */ - public static final int ICMP = 1; - /** - * Internet Group Management - */ - public static final int IGMP = 2; - /** - * Gateway-to-Gateway - */ - public static final int GGP = 3; - /** - * Stream - */ - public static final int ST = 5; - /** - * Transmission Control - */ - public static final int TCP = 6; - /** - * UCL - */ - public static final int UCL = 7; - /** - * Exterior Gateway Protocol - */ - public static final int EGP = 8; - /** - * any private interior gateway - */ - public static final int IGP = 9; - /** - * BBN RCC Monitoring - */ - public static final int BBN_RCC_MON = 10; - /** - * Network Voice Protocol - */ - public static final int NVP_II = 11; - /** - * PUP - */ - public static final int PUP = 12; - /** - * ARGUS - */ - public static final int ARGUS = 13; - /** - * EMCON - */ - public static final int EMCON = 14; - /** - * Cross Net Debugger - */ - public static final int XNET = 15; - /** - * Chaos - */ - public static final int CHAOS = 16; - /** - * User Datagram - */ - public static final int UDP = 17; - /** - * Multiplexing - */ - public static final int MUX = 18; - /** - * DCN Measurement Subsystems - */ - public static final int DCN_MEAS = 19; - /** - * Host Monitoring - */ - public static final int HMP = 20; - /** - * Packet Radio Measurement - */ - public static final int PRM = 21; - /** - * XEROX NS IDP - */ - public static final int XNS_IDP = 22; - /** - * Trunk-1 - */ - public static final int TRUNK_1 = 23; - /** - * Trunk-2 - */ - public static final int TRUNK_2 = 24; - /** - * Leaf-1 - */ - public static final int LEAF_1 = 25; - /** - * Leaf-2 - */ - public static final int LEAF_2 = 26; - /** - * Reliable Data Protocol - */ - public static final int RDP = 27; - /** - * Internet Reliable Transaction - */ - public static final int IRTP = 28; - /** - * ISO Transport Protocol Class 4 - */ - public static final int ISO_TP4 = 29; - /** - * Bulk Data Transfer Protocol - */ - public static final int NETBLT = 30; - /** - * MFE Network Services Protocol - */ - public static final int MFE_NSP = 31; - /** - * MERIT Internodal Protocol - */ - public static final int MERIT_INP = 32; - /** - * Sequential Exchange Protocol - */ - public static final int SEP = 33; - /** - * CFTP - */ - public static final int CFTP = 62; - /** - * SATNET and Backroom EXPAK - */ - public static final int SAT_EXPAK = 64; - /** - * MIT Subnet Support - */ - public static final int MIT_SUBNET = 65; - /** - * MIT Remote Virtual Disk Protocol - */ - public static final int RVD = 66; - /** - * Internet Pluribus Packet Core - */ - public static final int IPPC = 67; - /** - * SATNET Monitoring - */ - public static final int SAT_MON = 69; - /** - * Internet Packet Core Utility - */ - public static final int IPCV = 71; - /** - * Backroom SATNET Monitoring - */ - public static final int BR_SAT_MON = 76; - /** - * WIDEBAND Monitoring - */ - public static final int WB_MON = 78; - /** - * WIDEBAND EXPAK - */ - public static final int WB_EXPAK = 79; - private static Mnemonic protocols = new Mnemonic("IP protocol", Mnemonic.CASE_LOWER); - - /** - * IP protocol identifiers. This is basically copied out of RFC 1010. - */ - - private - Protocol() {} - - static { - protocols.setMaximum(0xFF); - protocols.setNumericAllowed(true); - - protocols.add(ICMP, "icmp"); - protocols.add(IGMP, "igmp"); - protocols.add(GGP, "ggp"); - protocols.add(ST, "st"); - protocols.add(TCP, "tcp"); - protocols.add(UCL, "ucl"); - protocols.add(EGP, "egp"); - protocols.add(IGP, "igp"); - protocols.add(BBN_RCC_MON, "bbn-rcc-mon"); - protocols.add(NVP_II, "nvp-ii"); - protocols.add(PUP, "pup"); - protocols.add(ARGUS, "argus"); - protocols.add(EMCON, "emcon"); - protocols.add(XNET, "xnet"); - protocols.add(CHAOS, "chaos"); - protocols.add(UDP, "udp"); - protocols.add(MUX, "mux"); - protocols.add(DCN_MEAS, "dcn-meas"); - protocols.add(HMP, "hmp"); - protocols.add(PRM, "prm"); - protocols.add(XNS_IDP, "xns-idp"); - protocols.add(TRUNK_1, "trunk-1"); - protocols.add(TRUNK_2, "trunk-2"); - protocols.add(LEAF_1, "leaf-1"); - protocols.add(LEAF_2, "leaf-2"); - protocols.add(RDP, "rdp"); - protocols.add(IRTP, "irtp"); - protocols.add(ISO_TP4, "iso-tp4"); - protocols.add(NETBLT, "netblt"); - protocols.add(MFE_NSP, "mfe-nsp"); - protocols.add(MERIT_INP, "merit-inp"); - protocols.add(SEP, "sep"); - protocols.add(CFTP, "cftp"); - protocols.add(SAT_EXPAK, "sat-expak"); - protocols.add(MIT_SUBNET, "mit-subnet"); - protocols.add(RVD, "rvd"); - protocols.add(IPPC, "ippc"); - protocols.add(SAT_MON, "sat-mon"); - protocols.add(IPCV, "ipcv"); - protocols.add(BR_SAT_MON, "br-sat-mon"); - protocols.add(WB_MON, "wb-mon"); - protocols.add(WB_EXPAK, "wb-expak"); - } - - /** - * Converts an IP protocol value into its textual representation - */ - public static - String string(int type) { - return protocols.getText(type); - } - - /** - * Converts a textual representation of an IP protocol into its - * numeric code. Integers in the range 0..255 are also accepted. - * - * @param s The textual representation of the protocol - * - * @return The protocol code, or -1 on error. - */ - public static - int value(String s) { - return protocols.getValue(s); - } - } - - - public static - class Service { - /** - * Remote Job Entry - */ - public static final int RJE = 5; - /** - * Echo - */ - public static final int ECHO = 7; - /** - * Discard - */ - public static final int DISCARD = 9; - /** - * Active Users - */ - public static final int USERS = 11; - /** - * Daytime - */ - public static final int DAYTIME = 13; - /** - * Quote of the Day - */ - public static final int QUOTE = 17; - /** - * Character Generator - */ - public static final int CHARGEN = 19; - /** - * File Transfer [Default Data] - */ - public static final int FTP_DATA = 20; - /** - * File Transfer [Control] - */ - public static final int FTP = 21; - /** - * Telnet - */ - public static final int TELNET = 23; - /** - * Simple Mail Transfer - */ - public static final int SMTP = 25; - /** - * NSW User System FE - */ - public static final int NSW_FE = 27; - /** - * MSG ICP - */ - public static final int MSG_ICP = 29; - /** - * MSG Authentication - */ - public static final int MSG_AUTH = 31; - /** - * Display Support Protocol - */ - public static final int DSP = 33; - /** - * Time - */ - public static final int TIME = 37; - /** - * Resource Location Protocol - */ - public static final int RLP = 39; - /** - * Graphics - */ - public static final int GRAPHICS = 41; - /** - * Host Name Server - */ - public static final int NAMESERVER = 42; - /** - * Who Is - */ - public static final int NICNAME = 43; - /** - * MPM FLAGS Protocol - */ - public static final int MPM_FLAGS = 44; - /** - * DnsMessage Processing Module [recv] - */ - public static final int MPM = 45; - /** - * MPM [default send] - */ - public static final int MPM_SND = 46; - /** - * NI FTP - */ - public static final int NI_FTP = 47; - /** - * Login Host Protocol - */ - public static final int LOGIN = 49; - /** - * IMP Logical Address Maintenance - */ - public static final int LA_MAINT = 51; - /** - * Domain Name Server - */ - public static final int DOMAIN = 53; - /** - * ISI Graphics Language - */ - public static final int ISI_GL = 55; - /** - * NI MAIL - */ - public static final int NI_MAIL = 61; - /** - * VIA Systems - FTP - */ - public static final int VIA_FTP = 63; - /** - * TACACS-Database Service - */ - public static final int TACACS_DS = 65; - /** - * Bootstrap Protocol Server - */ - public static final int BOOTPS = 67; - /** - * Bootstrap Protocol Client - */ - public static final int BOOTPC = 68; - /** - * Trivial File Transfer - */ - public static final int TFTP = 69; - /** - * Remote Job Service - */ - public static final int NETRJS_1 = 71; - /** - * Remote Job Service - */ - public static final int NETRJS_2 = 72; - /** - * Remote Job Service - */ - public static final int NETRJS_3 = 73; - /** - * Remote Job Service - */ - public static final int NETRJS_4 = 74; - /** - * Finger - */ - public static final int FINGER = 79; - /** - * HOSTS2 Name Server - */ - public static final int HOSTS2_NS = 81; - /** - * SU/MIT Telnet Gateway - */ - public static final int SU_MIT_TG = 89; - /** - * MIT Dover Spooler - */ - public static final int MIT_DOV = 91; - /** - * Device Control Protocol - */ - public static final int DCP = 93; - /** - * SUPDUP - */ - public static final int SUPDUP = 95; - /** - * Swift Remote Virtual File Protocol - */ - public static final int SWIFT_RVF = 97; - /** - * TAC News - */ - public static final int TACNEWS = 98; - /** - * Metagram Relay - */ - public static final int METAGRAM = 99; - /** - * NIC Host Name Server - */ - public static final int HOSTNAME = 101; - /** - * ISO-TSAP - */ - public static final int ISO_TSAP = 102; - /** - * X400 - */ - public static final int X400 = 103; - /** - * X400-SND - */ - public static final int X400_SND = 104; - /** - * Mailbox Name Nameserver - */ - public static final int CSNET_NS = 105; - /** - * Remote Telnet Service - */ - public static final int RTELNET = 107; - /** - * Post Office Protocol - Version 2 - */ - public static final int POP_2 = 109; - /** - * SUN Remote Procedure Call - */ - public static final int SUNRPC = 111; - /** - * Authentication Service - */ - public static final int AUTH = 113; - /** - * Simple File Transfer Protocol - */ - public static final int SFTP = 115; - /** - * UUCP Path Service - */ - public static final int UUCP_PATH = 117; - /** - * Network News Transfer Protocol - */ - public static final int NNTP = 119; - /** - * HYDRA Expedited Remote Procedure - */ - public static final int ERPC = 121; - /** - * Network Time Protocol - */ - public static final int NTP = 123; - /** - * Locus PC-Interface Net Map Server - */ - public static final int LOCUS_MAP = 125; - /** - * Locus PC-Interface Conn Server - */ - public static final int LOCUS_CON = 127; - /** - * Password Generator Protocol - */ - public static final int PWDGEN = 129; - /** - * CISCO FNATIVE - */ - public static final int CISCO_FNA = 130; - /** - * CISCO TNATIVE - */ - public static final int CISCO_TNA = 131; - /** - * CISCO SYSMAINT - */ - public static final int CISCO_SYS = 132; - /** - * Statistics Service - */ - public static final int STATSRV = 133; - /** - * INGRES-NET Service - */ - public static final int INGRES_NET = 134; - /** - * Location Service - */ - public static final int LOC_SRV = 135; - /** - * PROFILE Naming System - */ - public static final int PROFILE = 136; - /** - * NETBIOS Name Service - */ - public static final int NETBIOS_NS = 137; - /** - * NETBIOS Datagram Service - */ - public static final int NETBIOS_DGM = 138; - /** - * NETBIOS Session Service - */ - public static final int NETBIOS_SSN = 139; - /** - * EMFIS Data Service - */ - public static final int EMFIS_DATA = 140; - /** - * EMFIS Control Service - */ - public static final int EMFIS_CNTL = 141; - /** - * Britton-Lee IDM - */ - public static final int BL_IDM = 142; - /** - * Survey Measurement - */ - public static final int SUR_MEAS = 243; - /** - * LINK - */ - public static final int LINK = 245; - private static Mnemonic services = new Mnemonic("TCP/UDP service", Mnemonic.CASE_LOWER); - - /** - * TCP/UDP services. This is basically copied out of RFC 1010, - * with MIT-ML-DEV removed, as it is not unique, and the description - * of SWIFT-RVF fixed. - */ - - private - Service() {} - - static { - services.setMaximum(0xFFFF); - services.setNumericAllowed(true); - - services.add(RJE, "rje"); - services.add(ECHO, "echo"); - services.add(DISCARD, "discard"); - services.add(USERS, "users"); - services.add(DAYTIME, "daytime"); - services.add(QUOTE, "quote"); - services.add(CHARGEN, "chargen"); - services.add(FTP_DATA, "ftp-data"); - services.add(FTP, "ftp"); - services.add(TELNET, "telnet"); - services.add(SMTP, "smtp"); - services.add(NSW_FE, "nsw-fe"); - services.add(MSG_ICP, "msg-icp"); - services.add(MSG_AUTH, "msg-auth"); - services.add(DSP, "dsp"); - services.add(TIME, "time"); - services.add(RLP, "rlp"); - services.add(GRAPHICS, "graphics"); - services.add(NAMESERVER, "nameserver"); - services.add(NICNAME, "nicname"); - services.add(MPM_FLAGS, "mpm-flags"); - services.add(MPM, "mpm"); - services.add(MPM_SND, "mpm-snd"); - services.add(NI_FTP, "ni-ftp"); - services.add(LOGIN, "login"); - services.add(LA_MAINT, "la-maint"); - services.add(DOMAIN, "domain"); - services.add(ISI_GL, "isi-gl"); - services.add(NI_MAIL, "ni-mail"); - services.add(VIA_FTP, "via-ftp"); - services.add(TACACS_DS, "tacacs-ds"); - services.add(BOOTPS, "bootps"); - services.add(BOOTPC, "bootpc"); - services.add(TFTP, "tftp"); - services.add(NETRJS_1, "netrjs-1"); - services.add(NETRJS_2, "netrjs-2"); - services.add(NETRJS_3, "netrjs-3"); - services.add(NETRJS_4, "netrjs-4"); - services.add(FINGER, "finger"); - services.add(HOSTS2_NS, "hosts2-ns"); - services.add(SU_MIT_TG, "su-mit-tg"); - services.add(MIT_DOV, "mit-dov"); - services.add(DCP, "dcp"); - services.add(SUPDUP, "supdup"); - services.add(SWIFT_RVF, "swift-rvf"); - services.add(TACNEWS, "tacnews"); - services.add(METAGRAM, "metagram"); - services.add(HOSTNAME, "hostname"); - services.add(ISO_TSAP, "iso-tsap"); - services.add(X400, "x400"); - services.add(X400_SND, "x400-snd"); - services.add(CSNET_NS, "csnet-ns"); - services.add(RTELNET, "rtelnet"); - services.add(POP_2, "pop-2"); - services.add(SUNRPC, "sunrpc"); - services.add(AUTH, "auth"); - services.add(SFTP, "sftp"); - services.add(UUCP_PATH, "uucp-path"); - services.add(NNTP, "nntp"); - services.add(ERPC, "erpc"); - services.add(NTP, "ntp"); - services.add(LOCUS_MAP, "locus-map"); - services.add(LOCUS_CON, "locus-con"); - services.add(PWDGEN, "pwdgen"); - services.add(CISCO_FNA, "cisco-fna"); - services.add(CISCO_TNA, "cisco-tna"); - services.add(CISCO_SYS, "cisco-sys"); - services.add(STATSRV, "statsrv"); - services.add(INGRES_NET, "ingres-net"); - services.add(LOC_SRV, "loc-srv"); - services.add(PROFILE, "profile"); - services.add(NETBIOS_NS, "netbios-ns"); - services.add(NETBIOS_DGM, "netbios-dgm"); - services.add(NETBIOS_SSN, "netbios-ssn"); - services.add(EMFIS_DATA, "emfis-data"); - services.add(EMFIS_CNTL, "emfis-cntl"); - services.add(BL_IDM, "bl-idm"); - services.add(SUR_MEAS, "sur-meas"); - services.add(LINK, "link"); - } - - /** - * Converts a TCP/UDP service port number into its textual - * representation. - */ - public static - String string(int type) { - return services.getText(type); - } - - /** - * Converts a textual representation of a TCP/UDP service into its - * port number. Integers in the range 0..65535 are also accepted. - * - * @param s The textual representation of the service. - * - * @return The port number, or -1 on error. - */ - public static - int value(String s) { - return services.getValue(s); - } - } - - WKSRecord() {} - - @Override - DnsRecord getObject() { - return new WKSRecord(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - address = in.readByteArray(4); - protocol = in.readU8(); - byte[] array = in.readByteArray(); - List list = new ArrayList(); - for (int i = 0; i < array.length; i++) { - for (int j = 0; j < 8; j++) { - int octet = array[i] & 0xFF; - if ((octet & (1 << (7 - j))) != 0) { - list.add(new Integer(i * 8 + j)); - } - } - } - services = new int[list.size()]; - for (int i = 0; i < list.size(); i++) { - services[i] = ((Integer) list.get(i)).intValue(); - } - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeByteArray(address); - out.writeU8(protocol); - int highestPort = services[services.length - 1]; - byte[] array = new byte[highestPort / 8 + 1]; - for (int i = 0; i < services.length; i++) { - int port = services[i]; - array[port / 8] |= (1 << (7 - port % 8)); - } - out.writeByteArray(array); - } - - /** - * Converts rdata to a String - */ - @Override - void rrToString(StringBuilder sb) { - sb.append(Address.toDottedQuad(address)); - sb.append(" "); - sb.append(protocol); - for (int i = 0; i < services.length; i++) { - sb.append(" ") - .append(services[i]); - } - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - String s = st.getString(); - address = Address.toByteArray(s, Address.IPv4); - if (address == null) { - throw st.exception("invalid address"); - } - - s = st.getString(); - protocol = Protocol.value(s); - if (protocol < 0) { - throw st.exception("Invalid IP protocol: " + s); - } - - List list = new ArrayList(); - while (true) { - Tokenizer.Token t = st.get(); - if (!t.isString()) { - break; - } - int service = Service.value(t.value); - if (service < 0) { - throw st.exception("Invalid TCP/UDP service: " + t.value); - } - list.add(new Integer(service)); - } - st.unget(); - services = new int[list.size()]; - for (int i = 0; i < list.size(); i++) { - services[i] = ((Integer) list.get(i)).intValue(); - } - } - - /** - * Creates a WKS Record from the given data - * - * @param address The IP address - * @param protocol The IP protocol number - * @param services An array of supported services, represented by port number. - */ - public - WKSRecord(Name name, int dclass, long ttl, InetAddress address, int protocol, int[] services) { - super(name, DnsRecordType.WKS, dclass, ttl); - if (Address.familyOf(address) != Address.IPv4) { - throw new IllegalArgumentException("invalid IPv4 address"); - } - this.address = address.getAddress(); - this.protocol = checkU8("protocol", protocol); - for (int i = 0; i < services.length; i++) { - checkU16("service", services[i]); - } - this.services = new int[services.length]; - System.arraycopy(services, 0, this.services, 0, services.length); - Arrays.sort(this.services); - } - - /** - * Returns the IP address. - */ - public - InetAddress getAddress() { - try { - return InetAddress.getByAddress(address); - } catch (UnknownHostException e) { - return null; - } - } - - /** - * Returns the IP protocol. - */ - public - int getProtocol() { - return protocol; - } - - /** - * Returns the services provided by the host on the specified address. - */ - public - int[] getServices() { - return services; - } - -} diff --git a/src/dorkbox/network/dns/records/X25Record.java b/src/dorkbox/network/dns/records/X25Record.java deleted file mode 100644 index b5e2d55b..00000000 --- a/src/dorkbox/network/dns/records/X25Record.java +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.utils.Tokenizer; - -/** - * X25 - identifies the PSDN (Public Switched Data Network) address in the - * X.121 numbering plan associated with a name. - * - * @author Brian Wellington - */ - -public -class X25Record extends DnsRecord { - - private static final long serialVersionUID = 4267576252335579764L; - - private byte[] address; - - X25Record() {} - - @Override - DnsRecord getObject() { - return new X25Record(); - } - - @Override - void rrFromWire(DnsInput in) throws IOException { - address = in.readCountedString(); - } - - @Override - void rrToWire(DnsOutput out, Compression c, boolean canonical) { - out.writeCountedString(address); - } - - @Override - void rrToString(StringBuilder sb) { - sb.append(byteArrayToString(address, true)); - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - String addr = st.getString(); - this.address = checkAndConvertAddress(addr); - if (this.address == null) { - throw st.exception("invalid PSDN address " + addr); - } - } - - /** - * Creates an X25 Record from the given data - * - * @param address The X.25 PSDN address. - * - * @throws IllegalArgumentException The address is not a valid PSDN address. - */ - public - X25Record(Name name, int dclass, long ttl, String address) { - super(name, DnsRecordType.X25, dclass, ttl); - this.address = checkAndConvertAddress(address); - if (this.address == null) { - throw new IllegalArgumentException("invalid PSDN address " + address); - } - } - - private static - byte[] checkAndConvertAddress(String address) { - int length = address.length(); - byte[] out = new byte[length]; - for (int i = 0; i < length; i++) { - char c = address.charAt(i); - if (!Character.isDigit(c)) { - return null; - } - out[i] = (byte) c; - } - return out; - } - - /** - * Returns the X.25 PSDN address. - */ - public - String getAddress() { - return byteArrayToString(address, false); - } -} diff --git a/src/dorkbox/network/dns/resolver/BiDnsQueryLifecycleObserver.java b/src/dorkbox/network/dns/resolver/BiDnsQueryLifecycleObserver.java deleted file mode 100644 index 0e2d9d16..00000000 --- a/src/dorkbox/network/dns/resolver/BiDnsQueryLifecycleObserver.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import static io.netty.util.internal.ObjectUtil.checkNotNull; - -import java.net.InetSocketAddress; -import java.util.List; - -import dorkbox.network.dns.records.DnsMessage; -import io.netty.channel.ChannelFuture; -import io.netty.util.internal.UnstableApi; - -/** - * Combines two {@link DnsQueryLifecycleObserver} into a single {@link DnsQueryLifecycleObserver}. - */ -@UnstableApi -public final -class BiDnsQueryLifecycleObserver implements DnsQueryLifecycleObserver { - private final DnsQueryLifecycleObserver a; - private final DnsQueryLifecycleObserver b; - - /** - * Create a new instance. - * - * @param a The {@link DnsQueryLifecycleObserver} that will receive events first. - * @param b The {@link DnsQueryLifecycleObserver} that will receive events second. - */ - public - BiDnsQueryLifecycleObserver(DnsQueryLifecycleObserver a, DnsQueryLifecycleObserver b) { - this.a = checkNotNull(a, "a"); - this.b = checkNotNull(b, "b"); - } - - @Override - public - void queryWritten(InetSocketAddress dnsServerAddress, ChannelFuture future) { - try { - a.queryWritten(dnsServerAddress, future); - } finally { - b.queryWritten(dnsServerAddress, future); - } - } - - @Override - public - void queryCancelled(int queriesRemaining) { - try { - a.queryCancelled(queriesRemaining); - } finally { - b.queryCancelled(queriesRemaining); - } - } - - @Override - public - DnsQueryLifecycleObserver queryRedirected(List nameServers) { - try { - a.queryRedirected(nameServers); - } finally { - b.queryRedirected(nameServers); - } - return this; - } - - @Override - public - DnsQueryLifecycleObserver queryCNAMEd(DnsMessage cnameQuestion) { - try { - a.queryCNAMEd(cnameQuestion); - } finally { - b.queryCNAMEd(cnameQuestion); - } - return this; - } - - @Override - public - DnsQueryLifecycleObserver queryNoAnswer(int code) { - try { - a.queryNoAnswer(code); - } finally { - b.queryNoAnswer(code); - } - return this; - } - - @Override - public - void queryFailed(Throwable cause) { - try { - a.queryFailed(cause); - } finally { - b.queryFailed(cause); - } - } - - @Override - public - void querySucceed() { - try { - a.querySucceed(); - } finally { - b.querySucceed(); - } - } -} diff --git a/src/dorkbox/network/dns/resolver/BiDnsQueryLifecycleObserverFactory.java b/src/dorkbox/network/dns/resolver/BiDnsQueryLifecycleObserverFactory.java deleted file mode 100644 index a9462893..00000000 --- a/src/dorkbox/network/dns/resolver/BiDnsQueryLifecycleObserverFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import static io.netty.util.internal.ObjectUtil.checkNotNull; - -import dorkbox.network.dns.records.DnsMessage; -import io.netty.util.internal.UnstableApi; - -/** - * Combines two {@link DnsQueryLifecycleObserverFactory} into a single {@link DnsQueryLifecycleObserverFactory}. - */ -@UnstableApi -public final -class BiDnsQueryLifecycleObserverFactory implements DnsQueryLifecycleObserverFactory { - private final DnsQueryLifecycleObserverFactory a; - private final DnsQueryLifecycleObserverFactory b; - - /** - * Create a new instance. - * - * @param a The {@link DnsQueryLifecycleObserverFactory} that will receive events first. - * @param b The {@link DnsQueryLifecycleObserverFactory} that will receive events second. - */ - public - BiDnsQueryLifecycleObserverFactory(DnsQueryLifecycleObserverFactory a, DnsQueryLifecycleObserverFactory b) { - this.a = checkNotNull(a, "a"); - this.b = checkNotNull(b, "b"); - } - - @Override - public - DnsQueryLifecycleObserver newDnsQueryLifecycleObserver(DnsMessage question) { - return new BiDnsQueryLifecycleObserver(a.newDnsQueryLifecycleObserver(question), b.newDnsQueryLifecycleObserver(question)); - } -} diff --git a/src/dorkbox/network/dns/resolver/DnsNameResolver.java b/src/dorkbox/network/dns/resolver/DnsNameResolver.java deleted file mode 100644 index 27f93c0d..00000000 --- a/src/dorkbox/network/dns/resolver/DnsNameResolver.java +++ /dev/null @@ -1,809 +0,0 @@ -/* - * Copyright 2014 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import static io.netty.util.internal.ObjectUtil.checkNotNull; -import static io.netty.util.internal.ObjectUtil.checkPositive; - -import java.lang.reflect.Method; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import dorkbox.network.dns.DnsQuestion; -import dorkbox.network.dns.clientHandlers.DatagramDnsQueryEncoder; -import dorkbox.network.dns.clientHandlers.DatagramDnsResponseDecoder; -import dorkbox.network.dns.clientHandlers.DnsResponse; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.resolver.addressProvider.DefaultDnsServerAddressStreamProvider; -import dorkbox.network.dns.resolver.addressProvider.DnsServerAddressStream; -import dorkbox.network.dns.resolver.addressProvider.DnsServerAddressStreamProvider; -import dorkbox.network.dns.resolver.addressProvider.DnsServerAddresses; -import dorkbox.network.dns.resolver.addressProvider.UnixResolverDnsServerAddressStreamProvider; -import dorkbox.network.dns.resolver.cache.DnsCache; -import dorkbox.network.dns.resolver.cache.DnsCacheEntry; -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFactory; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelOption; -import io.netty.channel.ChannelPromise; -import io.netty.channel.EventLoop; -import io.netty.channel.FixedRecvByteBufAllocator; -import io.netty.channel.socket.DatagramChannel; -import io.netty.channel.socket.InternetProtocolFamily; -import io.netty.resolver.HostsFileEntriesResolver; -import io.netty.resolver.InetNameResolver; -import io.netty.resolver.ResolvedAddressTypes; -import io.netty.util.NetUtil; -import io.netty.util.concurrent.FastThreadLocal; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.Promise; -import io.netty.util.internal.EmptyArrays; -import io.netty.util.internal.PlatformDependent; -import io.netty.util.internal.UnstableApi; - -/** - * A DNS-based {@link InetNameResolver} - */ -@SuppressWarnings("unused") -@UnstableApi -public -class DnsNameResolver extends InetNameResolver { - - static final Logger logger = LoggerFactory.getLogger(DnsNameResolver.class); - - private static final String LOCALHOST = "localhost"; - private static final InetAddress LOCALHOST_ADDRESS; - - private static final int[] IPV4_ONLY_RESOLVED_RECORD_TYPES = {DnsRecordType.A}; - private static final InternetProtocolFamily[] IPV4_ONLY_RESOLVED_PROTOCOL_FAMILIES = {InternetProtocolFamily.IPv4}; - private static final int[] IPV4_PREFERRED_RESOLVED_RECORD_TYPES = {DnsRecordType.A, DnsRecordType.AAAA}; - private static final InternetProtocolFamily[] IPV4_PREFERRED_RESOLVED_PROTOCOL_FAMILIES = {InternetProtocolFamily.IPv4, - InternetProtocolFamily.IPv6}; - - private static final int[] IPV6_ONLY_RESOLVED_RECORD_TYPES = {DnsRecordType.AAAA}; - private static final InternetProtocolFamily[] IPV6_ONLY_RESOLVED_PROTOCOL_FAMILIES = {InternetProtocolFamily.IPv6}; - private static final int[] IPV6_PREFERRED_RESOLVED_RECORD_TYPES = {DnsRecordType.AAAA, DnsRecordType.A}; - private static final InternetProtocolFamily[] IPV6_PREFERRED_RESOLVED_PROTOCOL_FAMILIES = {InternetProtocolFamily.IPv6, - InternetProtocolFamily.IPv4}; - - public static final ResolvedAddressTypes DEFAULT_RESOLVE_ADDRESS_TYPES; - static final String[] DEFAULT_SEARCH_DOMAINS; - private static final int DEFAULT_NDOTS; - - private static final DatagramDnsResponseDecoder DNS_DECODER = new DatagramDnsResponseDecoder(); - private final DatagramDnsQueryEncoder DNS_ENCODER; - - final Future channelFuture; - final DatagramChannel ch; - - /** - * Manages the {@link DnsQueryContext}s in progress and their query IDs. - */ - final DnsQueryContextManager queryContextManager = new DnsQueryContextManager(); - - /** - * Cache for {@link #doResolve(String, Promise)} and {@link #doResolveAll(String, Promise)}. - */ - private final DnsCache resolveCache; - - - private final DnsCache authoritativeDnsServerCache; - - private final long queryTimeoutMillis; - private final int maxQueriesPerResolve; - - private final ResolvedAddressTypes resolvedAddressTypes; - private final InternetProtocolFamily[] resolvedInternetProtocolFamilies; - - private final boolean recursionDesired; - private final int maxPayloadSize; - - private final HostsFileEntriesResolver hostsFileEntriesResolver; - private final DnsServerAddressStreamProvider dnsServerAddressStreamProvider; - - private final FastThreadLocal nameServerAddrStream = new FastThreadLocal() { - @Override - protected - DnsServerAddressStream initialValue() throws Exception { - return dnsServerAddressStreamProvider.nameServerAddressStream(""); - } - }; - - private final String[] searchDomains; - private final int ndots; - - private final boolean supportsAAAARecords; - private final boolean supportsARecords; - - private final InternetProtocolFamily preferredAddressType; - private final int[] resolveRecordTypes; - - private final boolean decodeIdn; - - private final DnsQueryLifecycleObserverFactory dnsQueryLifecycleObserverFactory; - - static { - if (NetUtil.isIpV4StackPreferred()) { - DEFAULT_RESOLVE_ADDRESS_TYPES = ResolvedAddressTypes.IPV4_ONLY; - LOCALHOST_ADDRESS = NetUtil.LOCALHOST4; - } - else { - if (NetUtil.isIpV6AddressesPreferred()) { - DEFAULT_RESOLVE_ADDRESS_TYPES = ResolvedAddressTypes.IPV6_PREFERRED; - LOCALHOST_ADDRESS = NetUtil.LOCALHOST6; - } - else { - DEFAULT_RESOLVE_ADDRESS_TYPES = ResolvedAddressTypes.IPV4_PREFERRED; - LOCALHOST_ADDRESS = NetUtil.LOCALHOST4; - } - } - } - - static { - String[] searchDomains; - try { - Class configClass = Class.forName("sun.net.dns.ResolverConfiguration"); - Method open = configClass.getMethod("open"); - Method nameservers = configClass.getMethod("searchlist"); - Object instance = open.invoke(null); - - @SuppressWarnings("unchecked") - List list = (List) nameservers.invoke(instance); - searchDomains = list.toArray(new String[list.size()]); - } catch (Exception ignore) { - // Failed to get the system name search domain list. - searchDomains = EmptyArrays.EMPTY_STRINGS; - } - DEFAULT_SEARCH_DOMAINS = searchDomains; - - int ndots; - try { - ndots = UnixResolverDnsServerAddressStreamProvider.parseEtcResolverFirstNdots(); - } catch (Exception ignore) { - ndots = UnixResolverDnsServerAddressStreamProvider.DEFAULT_NDOTS; - } - DEFAULT_NDOTS = ndots; - } - - /** - * Creates a new DNS-based name resolver that communicates with the specified list of DNS servers. - * - * @param eventLoop the {@link EventLoop} which will perform the communication with the DNS servers - * @param channelFactory the {@link ChannelFactory} that will create a {@link DatagramChannel} - * @param resolveCache the DNS resolved entries cache - * @param authoritativeDnsServerCache the cache used to find the authoritative DNS server for a domain - * @param dnsQueryLifecycleObserverFactory used to generate new instances of {@link DnsQueryLifecycleObserver} which - * can be used to track metrics for DNS servers. - * @param queryTimeoutMillis timeout of each DNS query in millis - * @param resolvedAddressTypes the preferred address types - * @param recursionDesired if recursion desired flag must be set - * @param maxQueriesPerResolve the maximum allowed number of DNS queries for a given name resolution - * @param traceEnabled if trace is enabled - * @param maxPayloadSize the capacity of the datagram packet buffer - * @param hostsFileEntriesResolver the {@link HostsFileEntriesResolver} used to check for local aliases - * @param dnsServerAddressStreamProvider The {@link DnsServerAddressStreamProvider} used to determine the name - * servers for each hostname lookup. - * @param searchDomains the list of search domain - * (can be null, if so, will try to default to the underlying platform ones) - * @param ndots the ndots value - * @param decodeIdn {@code true} if domain / host names should be decoded to unicode when received. - * See rfc3492. - */ - public - DnsNameResolver(EventLoop eventLoop, - ChannelFactory channelFactory, - final DnsCache resolveCache, - DnsCache authoritativeDnsServerCache, - DnsQueryLifecycleObserverFactory dnsQueryLifecycleObserverFactory, - long queryTimeoutMillis, - ResolvedAddressTypes resolvedAddressTypes, - boolean recursionDesired, - int maxQueriesPerResolve, - boolean traceEnabled, - int maxPayloadSize, - HostsFileEntriesResolver hostsFileEntriesResolver, - DnsServerAddressStreamProvider dnsServerAddressStreamProvider, - String[] searchDomains, - int ndots, - boolean decodeIdn) { - super(eventLoop); - - this.queryTimeoutMillis = checkPositive(queryTimeoutMillis, "queryTimeoutMillis"); - this.resolvedAddressTypes = resolvedAddressTypes != null ? resolvedAddressTypes : DEFAULT_RESOLVE_ADDRESS_TYPES; - this.recursionDesired = recursionDesired; - this.maxQueriesPerResolve = checkPositive(maxQueriesPerResolve, "maxQueriesPerResolve"); - this.maxPayloadSize = checkPositive(maxPayloadSize, "maxPayloadSize"); - this.hostsFileEntriesResolver = checkNotNull(hostsFileEntriesResolver, "hostsFileEntriesResolver"); - this.dnsServerAddressStreamProvider = checkNotNull(dnsServerAddressStreamProvider, "dnsServerAddressStreamProvider"); - this.resolveCache = checkNotNull(resolveCache, "resolveCache"); - this.authoritativeDnsServerCache = checkNotNull(authoritativeDnsServerCache, "authoritativeDnsServerCache"); - - if (traceEnabled) { - if (dnsQueryLifecycleObserverFactory instanceof NoopDnsQueryLifecycleObserverFactory) { - this.dnsQueryLifecycleObserverFactory = new TraceDnsQueryLifeCycleObserverFactory(); - } - else { - this.dnsQueryLifecycleObserverFactory = new BiDnsQueryLifecycleObserverFactory(new TraceDnsQueryLifeCycleObserverFactory(), - dnsQueryLifecycleObserverFactory); - } - } - else { - this.dnsQueryLifecycleObserverFactory = checkNotNull(dnsQueryLifecycleObserverFactory, "dnsQueryLifecycleObserverFactory"); - } - - - this.searchDomains = searchDomains != null ? searchDomains.clone() : DEFAULT_SEARCH_DOMAINS; - this.ndots = ndots >= 0 ? ndots : DEFAULT_NDOTS; - this.decodeIdn = decodeIdn; - - switch (this.resolvedAddressTypes) { - case IPV4_ONLY: - supportsAAAARecords = false; - supportsARecords = true; - resolveRecordTypes = IPV4_ONLY_RESOLVED_RECORD_TYPES; - resolvedInternetProtocolFamilies = IPV4_ONLY_RESOLVED_PROTOCOL_FAMILIES; - preferredAddressType = InternetProtocolFamily.IPv4; - break; - case IPV4_PREFERRED: - supportsAAAARecords = true; - supportsARecords = true; - resolveRecordTypes = IPV4_PREFERRED_RESOLVED_RECORD_TYPES; - resolvedInternetProtocolFamilies = IPV4_PREFERRED_RESOLVED_PROTOCOL_FAMILIES; - preferredAddressType = InternetProtocolFamily.IPv4; - break; - case IPV6_ONLY: - supportsAAAARecords = true; - supportsARecords = false; - resolveRecordTypes = IPV6_ONLY_RESOLVED_RECORD_TYPES; - resolvedInternetProtocolFamilies = IPV6_ONLY_RESOLVED_PROTOCOL_FAMILIES; - preferredAddressType = InternetProtocolFamily.IPv6; - break; - case IPV6_PREFERRED: - supportsAAAARecords = true; - supportsARecords = true; - resolveRecordTypes = IPV6_PREFERRED_RESOLVED_RECORD_TYPES; - resolvedInternetProtocolFamilies = IPV6_PREFERRED_RESOLVED_PROTOCOL_FAMILIES; - preferredAddressType = InternetProtocolFamily.IPv6; - break; - default: - throw new IllegalArgumentException("Unknown ResolvedAddressTypes " + resolvedAddressTypes); - } - - Bootstrap b = new Bootstrap(); - b.group(executor()); - - b.channelFactory(channelFactory); - b.option(ChannelOption.DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION, true); - - DNS_ENCODER = new DatagramDnsQueryEncoder(maxPayloadSize); - - - Promise channelActivePromise = executor().newPromise(); - final DnsNameResolverResponseHandler responseHandler = new DnsNameResolverResponseHandler(this, channelActivePromise); - b.handler(new ChannelInitializer() { - @Override - protected - void initChannel(DatagramChannel ch) throws Exception { - ch.pipeline() - .addLast(DNS_DECODER, DNS_ENCODER, responseHandler); - } - }); - - channelFuture = channelActivePromise; - ch = (DatagramChannel) b.register() - .channel(); - - ch.config() - .setRecvByteBufAllocator(new FixedRecvByteBufAllocator(maxPayloadSize)); - - ch.closeFuture() - .addListener(new ChannelFutureListener() { - @Override - public - void operationComplete(ChannelFuture future) throws Exception { - resolveCache.clear(); - } - }); - } - - @Override - protected - EventLoop executor() { - return (EventLoop) super.executor(); - } - - @Override - protected - void doResolve(String inetHost, Promise promise) throws Exception { - doResolve(inetHost, promise, resolveCache); - } - - @Override - protected - void doResolveAll(String inetHost, Promise> promise) throws Exception { - doResolveAll(inetHost, promise, resolveCache); - } - - /** - * Closes the internal datagram channel used for sending and receiving DNS messages, and clears all DNS resource - * records from the cache. Attempting to send a DNS query or to resolve a domain name will fail once this method - * has been called. - */ - @Override - public - void close() { - if (ch.isOpen()) { - ch.close(); - } - } - - /** - * Hook designed for extensibility so one can pass a different cache on each resolution attempt - * instead of using the global one. - */ - protected - void doResolveAll(String inetHost, Promise> promise, DnsCache resolveCache) - throws Exception { - - if (inetHost == null || inetHost.isEmpty()) { - // If an empty hostname is used we should use "localhost", just like InetAddress.getAllByName(...) does. - promise.setSuccess(Collections.singletonList(loopbackAddress())); - return; - } - final byte[] bytes = NetUtil.createByteArrayFromIpAddressString(inetHost); - if (bytes != null) { - // The unresolvedAddress was created via a String that contains an ip address. - promise.setSuccess(Collections.singletonList(InetAddress.getByAddress(bytes))); - return; - } - - final String hostname = DnsQuestion.hostNameAsciiFix(inetHost); - - InetAddress hostsFileEntry = resolveHostsFileEntry(hostname); - if (hostsFileEntry != null) { - promise.setSuccess(Collections.singletonList(hostsFileEntry)); - return; - } - - if (!doResolveAllCached(hostname, promise, resolveCache)) { - doResolveAllUncached(hostname, promise, resolveCache); - } - } - - private - boolean doResolveAllCached(String hostname, Promise> promise, DnsCache resolveCache) { - - final List cachedEntries = resolveCache.get(hostname); - if (cachedEntries == null || cachedEntries.isEmpty()) { - return false; - } - - List result = null; - Throwable cause = null; - - //noinspection SynchronizationOnLocalVariableOrMethodParameter - synchronized (cachedEntries) { - final int numEntries = cachedEntries.size(); - assert numEntries > 0; - - if (cachedEntries.get(0) - .cause() != null) { - cause = cachedEntries.get(0) - .cause(); - } - else { - for (InternetProtocolFamily f : resolvedInternetProtocolFamilies) { - for (int i = 0; i < numEntries; i++) { - final DnsCacheEntry e = cachedEntries.get(i); - if (f.addressType() - .isInstance(e.address())) { - if (result == null) { - result = new ArrayList(numEntries); - } - result.add(e.address()); - } - } - } - } - } - - if (result != null) { - trySuccess(promise, result); - return true; - } - if (cause != null) { - tryFailure(promise, cause); - return true; - } - return false; - } - - private - void doResolveAllUncached(String hostname, Promise> promise, DnsCache resolveCache) { - DnsServerAddressStream nameServerAddrs = dnsServerAddressStreamProvider.nameServerAddressStream(hostname); - - DnsNameResolverListResolverContext context = new DnsNameResolverListResolverContext(this, hostname, resolveCache, nameServerAddrs); - context.resolve(promise); - } - - /** - * Hook designed for extensibility so one can pass a different cache on each resolution attempt - * instead of using the global one. - */ - protected - void doResolve(String inetHost, Promise promise, DnsCache resolveCache) throws Exception { - if (inetHost == null || inetHost.isEmpty()) { - // If an empty hostname is used we should use "localhost", just like InetAddress.getByName(...) does. - promise.setSuccess(loopbackAddress()); - return; - } - - final byte[] bytes = NetUtil.createByteArrayFromIpAddressString(inetHost); - if (bytes != null) { - // The inetHost is actually an ipaddress. - promise.setSuccess(InetAddress.getByAddress(bytes)); - return; - } - - final String hostname = DnsQuestion.hostNameAsciiFix(inetHost); - - InetAddress hostsFileEntry = resolveHostsFileEntry(hostname); - if (hostsFileEntry != null) { - promise.setSuccess(hostsFileEntry); - return; - } - - if (!doResolveCached(hostname, promise, resolveCache)) { - doResolveUncached(hostname, promise, resolveCache); - } - } - - public - InetAddress resolveHostsFileEntry(String hostname) { - if (hostsFileEntriesResolver == null) { - return null; - } - else { - InetAddress address = hostsFileEntriesResolver.address(hostname, resolvedAddressTypes); - if (address == null && PlatformDependent.isWindows() && LOCALHOST.equalsIgnoreCase(hostname)) { - // If we tried to resolve localhost we need workaround that windows removed localhost from its - // hostfile in later versions. - // See https://github.com/netty/netty/issues/5386 - return LOCALHOST_ADDRESS; - } - return address; - } - } - - private - InetAddress loopbackAddress() { - return preferredAddressType().localhost(); - } - - final - InternetProtocolFamily preferredAddressType() { - return preferredAddressType; - } - - private - boolean doResolveCached(String hostname, Promise promise, DnsCache resolveCache) { - final List cachedEntries = resolveCache.get(hostname); - if (cachedEntries == null || cachedEntries.isEmpty()) { - return false; - } - - InetAddress address = null; - Throwable cause = null; - ArrayList arrayList; - - //noinspection SynchronizationOnLocalVariableOrMethodParameter - synchronized (cachedEntries) { - final int numEntries = cachedEntries.size(); - assert numEntries > 0; - - if (cachedEntries.get(0) - .cause() != null) { - cause = cachedEntries.get(0) - .cause(); - } - else { - // Find the first entry with the preferred address type. - for (InternetProtocolFamily f : resolvedInternetProtocolFamilies) { - for (int i = 0; i < numEntries; i++) { - final DnsCacheEntry e = cachedEntries.get(i); - if (f.addressType() - .isInstance(e.address())) { - address = e.address(); - break; - } - } - } - } - } - - if (address != null) { - trySuccess(promise, address); - return true; - } - if (cause != null) { - tryFailure(promise, cause); - return true; - } - return false; - } - - static - void trySuccess(Promise promise, T result) { - if (!promise.trySuccess(result)) { - logger.warn("Failed to notify success ({}) to a promise: {}", result, promise); - } - } - - private static - void tryFailure(Promise promise, Throwable cause) { - if (!promise.tryFailure(cause)) { - logger.warn("Failed to notify failure to a promise: {}", promise, cause); - } - } - - private - void doResolveUncached(String hostname, Promise promise, DnsCache resolveCache) { - new DnsNameResolverSingleResolverContext(this, - hostname, - resolveCache, - dnsServerAddressStreamProvider.nameServerAddressStream(hostname)).resolve(promise); - } - - // Only here to override in unit tests. - int dnsRedirectPort(@SuppressWarnings("unused") InetAddress server) { - return DefaultDnsServerAddressStreamProvider.DNS_PORT; - } - - final - DnsQueryLifecycleObserverFactory dnsQueryLifecycleObserverFactory() { - return dnsQueryLifecycleObserverFactory; - } - - /** - * Provides the opportunity to sort the name servers before following a redirected DNS query. - * - * @param nameServers The addresses of the DNS servers which are used in the event of a redirect. - * - * @return A {@link DnsServerAddressStream} which will be used to follow the DNS redirect. - */ - protected - DnsServerAddressStream uncachedRedirectDnsServerStream(List nameServers) { - return DnsServerAddresses.sequential(nameServers) - .stream(); - } - - /** - * Returns the resolution cache. - */ - public - DnsCache resolveCache() { - return resolveCache; - } - - /** - * Returns the cache used for authoritative DNS servers for a domain. - */ - public - DnsCache authoritativeDnsServerCache() { - return authoritativeDnsServerCache; - } - - /** - * Returns the timeout of each DNS query performed by this resolver (in milliseconds). - * The default value is 5 seconds. - */ - public - long queryTimeoutMillis() { - return queryTimeoutMillis; - } - - /** - * Returns the {@link ResolvedAddressTypes} resolved by {@link #resolve(String)}. - * The default value depends on the value of the system property {@code "java.net.preferIPv6Addresses"}. - */ - public - ResolvedAddressTypes resolvedAddressTypes() { - return resolvedAddressTypes; - } - - InternetProtocolFamily[] resolvedInternetProtocolFamiliesUnsafe() { - return resolvedInternetProtocolFamilies; - } - - final - String[] searchDomains() { - return searchDomains; - } - - final - int ndots() { - return ndots; - } - - final - boolean supportsAAAARecords() { - return supportsAAAARecords; - } - - final - boolean supportsARecords() { - return supportsARecords; - } - - final - int[] resolveRecordTypes() { - return resolveRecordTypes; - } - - final - boolean isDecodeIdn() { - return decodeIdn; - } - - /** - * Returns the maximum allowed number of DNS queries to send when resolving a host name. - * The default value is {@code 8}. - */ - public - int maxQueriesPerResolve() { - return maxQueriesPerResolve; - } - - /** - * Returns the capacity of the datagram packet buffer (in bytes). The default value is {@code 4096} bytes. - */ - public - int maxPayloadSize() { - return maxPayloadSize; - } - - /** - * Returns the component that tries to resolve hostnames against the hosts file prior to asking to - * remotes DNS servers. - */ - public - HostsFileEntriesResolver hostsFileEntriesResolver() { - return hostsFileEntriesResolver; - } - - - /** - * Returns {@code true} if and only if this resolver sends a DNS query with the RD (recursion desired) flag set. - * The default value is {@code true}. - */ - public - boolean isRecursionDesired() { - return recursionDesired; - } - - - - /** - * Resolves the specified name into an address. - * - * @param inetHost the name to resolve - * @param promise the {@link Promise} which will be fulfilled when the name resolution is finished - * - * @return the address as the result of the resolution - */ - @Override - public final - Future resolve(String inetHost, Promise promise) { - checkNotNull(promise, "promise"); - try { - doResolve(inetHost, promise, resolveCache); - return promise; - } catch (Exception e) { - return promise.setFailure(e); - } - } - - /** - * Resolves the specified host name and port into a list of address. - * - * @param inetHost the name to resolve - * @param promise the {@link Promise} which will be fulfilled when the name resolution is finished - * - * @return the list of the address as the result of the resolution - */ - @Override - public final - Future> resolveAll(String inetHost, Promise> promise) { - checkNotNull(promise, "promise"); - try { - doResolveAll(inetHost, promise, resolveCache); - return promise; - } catch (Exception e) { - return promise.setFailure(e); - } - } - - /** - * Sends a DNS query with the specified question. - */ - public - Future query(DnsQuestion question) { - return query(nextNameServerAddress(), question); - } - - private - InetSocketAddress nextNameServerAddress() { - return nameServerAddrStream.get() - .next(); - } - - /** - * Sends a DNS query with the specified question using the specified name server list. - */ - public - Future query(InetSocketAddress nameServerAddr, DnsQuestion question) { - return query0(nameServerAddr, - question, - ch.eventLoop().newPromise()); - } - - final - Future query0(InetSocketAddress nameServerAddr, - DnsQuestion question, - Promise promise) { - return query0(nameServerAddr, question, ch.newPromise(), promise); - } - - final - Future query0(InetSocketAddress nameServerAddr, - DnsQuestion question, - ChannelPromise writePromise, - Promise promise) { - assert !writePromise.isVoid(); - - try { - new DnsQueryContext(this, nameServerAddr, question, promise).query(writePromise); - return promise; - } catch (Exception e) { - return promise.setFailure(e); - } - } - - /** - * Sends a DNS query with the specified question. - */ - public - Future query(DnsQuestion question, Promise promise) { - return query(nextNameServerAddress(), question, promise); - } - - /** - * Sends a DNS query with the specified question using the specified name server list. - */ - public - Future query(InetSocketAddress nameServerAddr, DnsQuestion question, Promise promise) { - return query0(nameServerAddr, question, null, promise); - } -} diff --git a/src/dorkbox/network/dns/resolver/DnsNameResolverContext.java b/src/dorkbox/network/dns/resolver/DnsNameResolverContext.java deleted file mode 100644 index 8eaa7254..00000000 --- a/src/dorkbox/network/dns/resolver/DnsNameResolverContext.java +++ /dev/null @@ -1,967 +0,0 @@ -/* - * Copyright 2014 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import static java.lang.Math.min; -import static java.util.Collections.unmodifiableList; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import dorkbox.network.dns.DnsQuestion; -import dorkbox.network.dns.clientHandlers.DnsResponse; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.records.AAAARecord; -import dorkbox.network.dns.records.ARecord; -import dorkbox.network.dns.records.CNAMERecord; -import dorkbox.network.dns.records.DnsMessage; -import dorkbox.network.dns.records.DnsRecord; -import dorkbox.network.dns.records.NSRecord; -import dorkbox.network.dns.resolver.addressProvider.DnsServerAddressStream; -import dorkbox.network.dns.resolver.addressProvider.DnsServerAddresses; -import dorkbox.network.dns.resolver.cache.DnsCache; -import dorkbox.network.dns.resolver.cache.DnsCacheEntry; -import io.netty.channel.ChannelPromise; -import io.netty.channel.socket.InternetProtocolFamily; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; -import io.netty.util.concurrent.Promise; -import io.netty.util.internal.ObjectUtil; -import io.netty.util.internal.PlatformDependent; -import io.netty.util.internal.StringUtil; -import io.netty.util.internal.ThrowableUtil; - -abstract -class DnsNameResolverContext { - - private static final FutureListener RELEASE_RESPONSE = new FutureListener() { - @Override - public - void operationComplete(Future future) { - if (future.isSuccess()) { - future.getNow() - .release(); - } - } - }; - - private static final RuntimeException NXDOMAIN_QUERY_FAILED_EXCEPTION = - ThrowableUtil.unknownStackTrace(new RuntimeException("No answer found and NXDOMAIN response code returned"), - DnsNameResolverContext.class, - "onResponse(..)"); - - private static final RuntimeException CNAME_NOT_FOUND_QUERY_FAILED_EXCEPTION = - ThrowableUtil.unknownStackTrace(new RuntimeException("No matching CNAME record found"), - DnsNameResolverContext.class, - "onResponseCNAME(..)"); - - private static final RuntimeException NO_MATCHING_RECORD_QUERY_FAILED_EXCEPTION = - ThrowableUtil.unknownStackTrace(new RuntimeException("No matching record type found"), - DnsNameResolverContext.class, - "onResponseAorAAAA(..)"); - - private static final RuntimeException UNRECOGNIZED_TYPE_QUERY_FAILED_EXCEPTION = - ThrowableUtil.unknownStackTrace(new RuntimeException("Response type was unrecognized"), - DnsNameResolverContext.class, - "onResponse(..)"); - - private static final RuntimeException NAME_SERVERS_EXHAUSTED_EXCEPTION = - ThrowableUtil.unknownStackTrace(new RuntimeException("No name servers returned an answer"), - DnsNameResolverContext.class, - "tryToFinishResolve(..)"); - - private final DnsNameResolver parent; - private final DnsServerAddressStream nameServerAddrs; - private final String hostname; - private final DnsCache resolveCache; - private final int maxAllowedQueries; - private final InternetProtocolFamily[] resolvedInternetProtocolFamilies; - - private final Set> queriesInProgress = Collections.newSetFromMap(new IdentityHashMap, Boolean>()); - - private List resolvedEntries; - private int allowedQueries; - private boolean triedCNAME; - - DnsNameResolverContext(DnsNameResolver parent, - String hostname, - DnsCache resolveCache, - DnsServerAddressStream nameServerAddrs) { - this.parent = parent; - this.hostname = hostname; - this.resolveCache = resolveCache; - - this.nameServerAddrs = ObjectUtil.checkNotNull(nameServerAddrs, "nameServerAddrs"); - - maxAllowedQueries = parent.maxQueriesPerResolve(); - resolvedInternetProtocolFamilies = parent.resolvedInternetProtocolFamiliesUnsafe(); - allowedQueries = maxAllowedQueries; - } - - void resolve(final Promise promise) { - if (parent.searchDomains().length == 0 || parent.ndots() == 0 || StringUtil.endsWith(hostname, '.')) { - internalResolve(promise); - } - else { - int dots = 0; - for (int idx = hostname.length() - 1; idx >= 0; idx--) { - if (hostname.charAt(idx) == '.' && ++dots >= parent.ndots()) { - internalResolve(promise); - return; - } - } - - doSearchDomainQuery(0, new FutureListener() { - private int count = 1; - - @Override - public - void operationComplete(Future future) throws Exception { - if (future.isSuccess()) { - promise.trySuccess(future.getNow()); - } - else if (count < parent.searchDomains().length) { - doSearchDomainQuery(count++, this); - } - else { - promise.tryFailure(new SearchDomainUnknownHostException(future.cause(), hostname)); - } - } - }); - } - } - - private static final - class SearchDomainUnknownHostException extends UnknownHostException { - SearchDomainUnknownHostException(Throwable cause, String originalHostname) { - super("Search domain query failed. Original hostname: '" + originalHostname + "' " + cause.getMessage()); - setStackTrace(cause.getStackTrace()); - } - - @Override - public - Throwable fillInStackTrace() { - return this; - } - } - - private - void doSearchDomainQuery(int count, FutureListener listener) { - DnsNameResolverContext nextContext = newResolverContext(parent, - hostname + '.' + parent.searchDomains()[count], - resolveCache, - nameServerAddrs); - Promise nextPromise = parent.executor() - .newPromise(); - nextPromise.addListener(listener); - nextContext.internalResolve(nextPromise); - } - - private - void internalResolve(Promise promise) { - DnsServerAddressStream nameServerAddressStream = getNameServers(hostname); - - int[] recordTypes = parent.resolveRecordTypes(); - assert recordTypes.length > 0; - final int end = recordTypes.length - 1; - - for (int i = 0; i < end; ++i) { - if (!resolveQuery(hostname, recordTypes[i], nameServerAddressStream.duplicate(), promise)) { - return; - } - } - - resolveQuery(hostname, recordTypes[end], nameServerAddressStream, promise); - } - - /** - * Add an authoritative nameserver to the cache if its not a root server. - */ - private - void addNameServerToCache(AuthoritativeNameServer name, InetAddress resolved, long ttl) { - if (!name.isRootServer()) { - // Cache NS record if not for a root server as we should never cache for root servers. - parent.authoritativeDnsServerCache() - .cache(name.domainName(), resolved, ttl, parent.ch.eventLoop()); - } - } - - /** - * Returns the {@link DnsServerAddressStream} that was cached for the given hostname or {@code null} if non - * could be found. - */ - private - DnsServerAddressStream getNameServersFromCache(String hostname) { - int len = hostname.length(); - - if (len == 0) { - // We never cache for root servers. - return null; - } - - // We always store in the cache with a trailing '.'. - if (hostname.charAt(len - 1) != '.') { - hostname += "."; - } - - int idx = hostname.indexOf('.'); - if (idx == hostname.length() - 1) { - // We are not interested in handling '.' as we should never serve the root servers from cache. - return null; - } - - // We start from the closed match and then move down. - for (; ; ) { - // Skip '.' as well. - hostname = hostname.substring(idx + 1); - - int idx2 = hostname.indexOf('.'); - if (idx2 <= 0 || idx2 == hostname.length() - 1) { - // We are not interested in handling '.TLD.' as we should never serve the root servers from cache. - return null; - } - idx = idx2; - - List entries = parent.authoritativeDnsServerCache().get(hostname); - if (entries != null && !entries.isEmpty()) { - return DnsServerAddresses.sequential(new DnsCacheIterable(entries)) - .stream(); - } - } - } - - private final - class DnsCacheIterable implements Iterable { - private final List entries; - - DnsCacheIterable(List entries) { - this.entries = entries; - } - - @Override - public - Iterator iterator() { - return new Iterator() { - Iterator entryIterator = entries.iterator(); - - @Override - public - boolean hasNext() { - return entryIterator.hasNext(); - } - - @Override - public - InetSocketAddress next() { - InetAddress address = entryIterator.next() - .address(); - return new InetSocketAddress(address, parent.dnsRedirectPort(address)); - } - - @Override - public - void remove() { - entryIterator.remove(); - } - }; - } - } - - private - void resolveQuery(final DnsServerAddressStream nameServerAddrStream, - final int nameServerAddrStreamIndex, - final DnsQuestion question, - final Promise promise) { - - resolveQuery(nameServerAddrStream, - nameServerAddrStreamIndex, - question, - parent.dnsQueryLifecycleObserverFactory().newDnsQueryLifecycleObserver(question), - promise); - } - - private - void resolveQuery(final DnsServerAddressStream nameServerAddrStream, - final int nameServerAddrStreamIndex, - final DnsQuestion question, - final DnsQueryLifecycleObserver queryLifecycleObserver, - final Promise promise) { - // question should have refCnt=2 - if (nameServerAddrStreamIndex >= nameServerAddrStream.size() || allowedQueries == 0 || promise.isCancelled()) { - tryToFinishResolve(nameServerAddrStream, nameServerAddrStreamIndex, question, queryLifecycleObserver, promise); - return; - } - - --allowedQueries; - - final InetSocketAddress nameServerAddr = nameServerAddrStream.next(); - final ChannelPromise writePromise = parent.ch.newPromise(); - final Future f = - parent.query0(nameServerAddr, - question, - writePromise, - parent.ch.eventLoop().newPromise()); - - queriesInProgress.add(f); - - queryLifecycleObserver.queryWritten(nameServerAddr, writePromise); - - f.addListener(new FutureListener() { - @Override - public - void operationComplete(Future future) { - // future.result() should have refCnt=2 - // question should have refCnt=1 - queriesInProgress.remove(future); - - if (promise.isDone() || future.isCancelled()) { - queryLifecycleObserver.queryCancelled(allowedQueries); - - - // Check if we need to release the envelope itself. If the query was cancelled the getNow() will - // return null as well as the Future will be failed with a CancellationException. - DnsResponse result = future.getNow(); - if (result != null) { - result.release(); - } - - return; - } - - DnsResponse envelope = future.getNow(); - try { - if (future.isSuccess()) { - onResponse(nameServerAddrStream, - nameServerAddrStreamIndex, - question, - envelope, - queryLifecycleObserver, - promise); - } - else { - // Server did not respond or I/O error occurred; try again. - queryLifecycleObserver.queryFailed(future.cause()); - - // query uses the question again... - question.retain(); - resolveQuery(nameServerAddrStream, nameServerAddrStreamIndex + 1, question, promise); - } - } finally { - // future.result() should have refCnt=2 - // question should have refCnt=1 - tryToFinishResolve(nameServerAddrStream, nameServerAddrStreamIndex, question, - // queryLifecycleObserver has already been terminated at this point so we must - // not allow it to be terminated again by tryToFinishResolve. - NoopDnsQueryLifecycleObserver.INSTANCE, promise); - } - } - }); - } - - void onResponse(final DnsServerAddressStream nameServerAddrStream, - final int nameServerAddrStreamIndex, - final DnsQuestion question, DnsResponse response, - final DnsQueryLifecycleObserver queryLifecycleObserver, - Promise promise) { - - final int code = response.getHeader() - .getRcode(); - - if (code == DnsResponseCode.NOERROR) { - if (handleRedirect(question, response, queryLifecycleObserver, promise)) { - // Was a redirect so return here as everything else is handled in handleRedirect(...) - return; - } - final int type = question.getQuestion() - .getType(); - - if (type == DnsRecordType.A || type == DnsRecordType.AAAA) { - onResponseAorAAAA(type, question, response, queryLifecycleObserver, promise); - } - else if (type == DnsRecordType.CNAME) { - onResponseCNAME(question, response, queryLifecycleObserver, promise); - } - else { - queryLifecycleObserver.queryFailed(UNRECOGNIZED_TYPE_QUERY_FAILED_EXCEPTION); - } - return; - } - - // Retry with the next server if the server did not tell us that the domain does not exist. - if (code != DnsResponseCode.NXDOMAIN) { - resolveQuery(nameServerAddrStream, - nameServerAddrStreamIndex + 1, - question, - queryLifecycleObserver.queryNoAnswer(code), - promise); - } - else { - queryLifecycleObserver.queryFailed(NXDOMAIN_QUERY_FAILED_EXCEPTION); - } - } - - /** - * Handles a redirect answer if needed and returns {@code true} if a redirect query has been made. - */ - private - boolean handleRedirect(DnsQuestion question, DnsResponse response, - final DnsQueryLifecycleObserver queryLifecycleObserver, - Promise promise) { - - // Check if we have answers, if not this may be an non authority NS and so redirects must be handled. - DnsRecord[] answerArray = response.getSectionArray(DnsSection.ANSWER); - if (answerArray.length == 0) { - AuthoritativeNameServerList serverNames = extractAuthoritativeNameServers(question.getQuestion() - .getName() - .toString(), response); - - if (serverNames != null) { - List nameServers = new ArrayList(serverNames.size()); - DnsRecord[] additionalArray = response.getSectionArray(DnsSection.ADDITIONAL); - - for (int i = 0; i < additionalArray.length; i++) { - final DnsRecord r = additionalArray[i]; - - if (r.getType() == DnsRecordType.A && !parent.supportsARecords() || - r.getType() == DnsRecordType.AAAA && !parent.supportsAAAARecords()) { - continue; - } - - final String recordName = r.getName() - .toString(); - AuthoritativeNameServer authoritativeNameServer = serverNames.remove(recordName); - - if (authoritativeNameServer == null) { - // Not a server we are interested in. - continue; - } - - InetAddress resolved = parseAddress(r, recordName); - if (resolved == null) { - // Could not parse it, move to the next. - continue; - } - - nameServers.add(new InetSocketAddress(resolved, parent.dnsRedirectPort(resolved))); - addNameServerToCache(authoritativeNameServer, resolved, r.getTTL()); - } - - if (!nameServers.isEmpty()) { - resolveQuery(parent.uncachedRedirectDnsServerStream(nameServers), - 0, - question, - queryLifecycleObserver.queryRedirected(unmodifiableList(nameServers)), - promise); - return true; - } - } - } - return false; - } - - /** - * Returns the {@code {@link AuthoritativeNameServerList} which were included in {@link DnsSection#AUTHORITY} - * or {@code null} if non are found. - */ - private static - AuthoritativeNameServerList extractAuthoritativeNameServers(String questionName, DnsResponse res) { - DnsRecord[] authority = res.getSectionArray(DnsSection.AUTHORITY); - if (authority.length == 0) { - return null; - } - - System.err.println("TYODO"); - AuthoritativeNameServerList serverNames = new AuthoritativeNameServerList(questionName); - for (int i = 0; i < authority.length; i++) { - final DnsRecord dnsRecord = authority[i]; - serverNames.add(dnsRecord); - } - - return serverNames; - } - - private - void onResponseAorAAAA(int qType, - DnsMessage question, DnsResponse response, - final DnsQueryLifecycleObserver queryLifecycleObserver, - Promise promise) { - - // We often get a bunch of CNAMES as well when we asked for A/AAAA. - final Map cnames = buildAliasMap(response); - - DnsRecord[] answerArray = response.getSectionArray(DnsSection.ANSWER); - - boolean found = false; - for (int i = 0; i < answerArray.length; i++) { - final DnsRecord r = answerArray[i]; - final int type = r.getType(); - if (type != DnsRecordType.A && type != DnsRecordType.AAAA) { - continue; - } - - final String questionName = question.getQuestion() - .getName() - .toString(); - final String recordName = r.getName() - .toString(); - - // Make sure the record is for the questioned domain. - if (!recordName.equals(questionName)) { - // Even if the record's name is not exactly same, it might be an alias defined in the CNAME records. - String resolved = questionName; - do { - resolved = cnames.get(resolved); - if (recordName.equals(resolved)) { - break; - } - } while (resolved != null); - - if (resolved == null) { - continue; - } - } - - InetAddress resolved = parseAddress(r, hostname); - if (resolved == null) { - continue; - } - - if (resolvedEntries == null) { - resolvedEntries = new ArrayList(8); - } - - final DnsCacheEntry e = new DnsCacheEntry(hostname, resolved); - resolveCache.cache(hostname, resolved, r.getTTL(), parent.ch.eventLoop()); - resolvedEntries.add(e); - found = true; - - // Note that we do not break from the loop here, so we decode/cache all A/AAAA records. - } - - if (found) { - queryLifecycleObserver.querySucceed(); - return; - } - - if (cnames.isEmpty()) { - queryLifecycleObserver.queryFailed(NO_MATCHING_RECORD_QUERY_FAILED_EXCEPTION); - } - else { - // We asked for A/AAAA but we got only CNAME. - onResponseCNAME(question, response, cnames, queryLifecycleObserver, promise); - } - } - - private - InetAddress parseAddress(DnsRecord record, String name) { - int type = record.getType(); - - if (type == DnsRecordType.A) { - ARecord aRecord = (ARecord) record; - return aRecord.getAddress(); - } - else if (type == DnsRecordType.AAAA) { - AAAARecord aaaaRecord = (AAAARecord) record; - return aaaaRecord.getAddress(); - } - else { - return null; - } - } - - private - void onResponseCNAME(DnsMessage question, DnsResponse response, - final DnsQueryLifecycleObserver queryLifecycleObserver, - Promise promise) { - onResponseCNAME(question, response, buildAliasMap(response), queryLifecycleObserver, promise); - } - - private - void onResponseCNAME(DnsMessage question, DnsResponse response, - Map cnames, - final DnsQueryLifecycleObserver queryLifecycleObserver, - Promise promise) { - - // Resolve the host name in the question into the real host name. - String resolved = question.getQuestion() - .getName() - .toString(); - boolean found = false; - while (!cnames.isEmpty()) { // Do not attempt to call Map.remove() when the Map is empty - // because it can be Collections.emptyMap() - // whose remove() throws a UnsupportedOperationException. - final String next = cnames.remove(resolved); - if (next != null) { - found = true; - resolved = next; - } - else { - break; - } - } - - if (found) { - followCname(resolved, queryLifecycleObserver, promise); - } - else { - queryLifecycleObserver.queryFailed(CNAME_NOT_FOUND_QUERY_FAILED_EXCEPTION); - } - } - - private static - Map buildAliasMap(DnsMessage response) { - DnsRecord[] answerArray = response.getSectionArray(DnsSection.ANSWER); - Map cnames = null; - int length = answerArray.length; - for (int i = 0; i < length; i++) { - final DnsRecord record = answerArray[i]; - final int type = record.getType(); - if (type != DnsRecordType.CNAME) { - continue; - } - - System.err.println("CHECK ME ME! we don't have bytebuf content in this fashion anymore"); - CNAMERecord re = (CNAMERecord) record; - final String domainName = re.getAlias() - .toString(); - - if (domainName == null) { - continue; - } - - if (cnames == null) { - cnames = new HashMap(min(8, length)); - } - - cnames.put(record.getName() - .toString() - .toLowerCase(Locale.US), domainName.toLowerCase(Locale.US)); - } - - return cnames != null ? cnames : Collections.emptyMap(); - } - - void tryToFinishResolve(final DnsServerAddressStream nameServerAddrStream, - final int nameServerAddrStreamIndex, - final DnsQuestion question, - final DnsQueryLifecycleObserver queryLifecycleObserver, - final Promise promise) { - // There are no queries left to try. - if (!queriesInProgress.isEmpty()) { - queryLifecycleObserver.queryCancelled(allowedQueries); - - // There are still some queries we did not receive responses for. - if (gotPreferredAddress()) { - // But it's OK to finish the resolution process if we got a resolved address of the preferred type. - finishResolve(promise, question); - } - - // We did not get any resolved address of the preferred type, so we can't finish the resolution process. - return; - } - - // There are no queries left to try. - if (resolvedEntries == null) { - if (nameServerAddrStreamIndex < nameServerAddrStream.size()) { - // the query is going to use the question again... - question.retain(); - if (queryLifecycleObserver == NoopDnsQueryLifecycleObserver.INSTANCE) { - // If the queryLifecycleObserver has already been terminated we should create a new one for this - // fresh query. - resolveQuery(nameServerAddrStream, nameServerAddrStreamIndex + 1, question, promise); - } - else { - resolveQuery(nameServerAddrStream, nameServerAddrStreamIndex + 1, question, queryLifecycleObserver, promise); - } - return; - } - - queryLifecycleObserver.queryFailed(NAME_SERVERS_EXHAUSTED_EXCEPTION); - - // .. and we could not find any A/AAAA records. - if (!triedCNAME) { - // As the last resort, try to query CNAME, just in case the name server has it. - triedCNAME = true; - - resolveQuery(hostname, DnsRecordType.CNAME, getNameServers(hostname), promise); - return; - } - } - else { - queryLifecycleObserver.queryCancelled(allowedQueries); - } - - // We have at least one resolved address or tried CNAME as the last resort.. - finishResolve(promise, question); - } - - private - boolean gotPreferredAddress() { - if (resolvedEntries == null) { - return false; - } - - final int size = resolvedEntries.size(); - final Class inetAddressType = parent.preferredAddressType() - .addressType(); - for (int i = 0; i < size; i++) { - InetAddress address = resolvedEntries.get(i) - .address(); - if (inetAddressType.isInstance(address)) { - return true; - } - } - return false; - } - - private - void finishResolve(Promise promise, final DnsQuestion question) { - // now we are done with the question. - question.release(); - - if (!queriesInProgress.isEmpty()) { - // If there are queries in progress, we should cancel it because we already finished the resolution. - for (Iterator> i = queriesInProgress.iterator(); i.hasNext(); ) { - Future f = i.next(); - i.remove(); - - if (!f.cancel(false)) { - f.addListener(RELEASE_RESPONSE); - } - } - } - - if (resolvedEntries != null) { - // Found at least one resolved address. - for (InternetProtocolFamily f : resolvedInternetProtocolFamilies) { - if (finishResolve(f.addressType(), resolvedEntries, promise)) { - return; - } - } - } - - // No resolved address found. - final int tries = maxAllowedQueries - allowedQueries; - final StringBuilder buf = new StringBuilder(64); - - buf.append("failed to resolve '") - .append(hostname) - .append('\''); - if (tries > 1) { - if (tries < maxAllowedQueries) { - buf.append(" after ") - .append(tries) - .append(" queries "); - } - else { - buf.append(". Exceeded max queries per resolve ") - .append(maxAllowedQueries) - .append(' '); - } - } - - final UnknownHostException cause = new UnknownHostException(buf.toString()); - cause.setStackTrace(new StackTraceElement[0]); - - resolveCache.cache(hostname, cause, parent.ch.eventLoop()); - promise.tryFailure(cause); - } - - abstract - boolean finishResolve(Class addressType, List resolvedEntries, Promise promise); - - abstract - DnsNameResolverContext newResolverContext(DnsNameResolver parent, - String hostname, - DnsCache resolveCache, - DnsServerAddressStream nameServerAddrs); - - private - DnsServerAddressStream getNameServers(String hostname) { - DnsServerAddressStream stream = getNameServersFromCache(hostname); - return stream == null ? nameServerAddrs : stream; - } - - private - void followCname(String cname, final DnsQueryLifecycleObserver queryLifecycleObserver, Promise promise) { - - // Use the same server for both CNAME queries - DnsServerAddressStream stream = DnsServerAddresses.singleton(getNameServers(cname).next()) - .stream(); - DnsQuestion cnameQuestion = null; - try { - if (parent.supportsARecords()) { - cnameQuestion = DnsQuestion.newResolveQuestion(hostname, DnsRecordType.A, parent.isRecursionDesired()); - } - if (parent.supportsAAAARecords()) { - cnameQuestion = DnsQuestion.newResolveQuestion(hostname, DnsRecordType.AAAA, parent.isRecursionDesired()); - } - - } catch (Throwable cause) { - queryLifecycleObserver.queryFailed(cause); - PlatformDependent.throwException(cause); - } - - if (cnameQuestion != null) { - resolveQuery(stream, 0, cnameQuestion, queryLifecycleObserver.queryCNAMEd(cnameQuestion), promise); - } - } - - private - boolean resolveQuery(String hostname, int type, DnsServerAddressStream dnsServerAddressStream, Promise promise) { - - DnsQuestion message = DnsQuestion.newResolveQuestion(hostname, type, parent.isRecursionDesired()); - if (message == null) { - return false; - } - - resolveQuery(dnsServerAddressStream, 0, message, promise); - return true; - } - - /** - * Holds the closed DNS Servers for a domain. - */ - private static final - class AuthoritativeNameServerList { - - private final String questionName; - - // We not expect the linked-list to be very long so a double-linked-list is overkill. - private AuthoritativeNameServer head; - private int count; - - AuthoritativeNameServerList(String questionName) { - this.questionName = questionName.toLowerCase(Locale.US); - } - - void add(DnsRecord record) { - if (record.getType() != DnsRecordType.NS) { - return; - } - - // Only include servers that serve the correct domain. - String recordName = record.getName() - .toString(); - if (questionName.length() < recordName.length()) { - return; - } - - int dots = 0; - for (int a = recordName.length() - 1, b = questionName.length() - 1; a >= 0; a--, b--) { - char c = recordName.charAt(a); - if (questionName.charAt(b) != c) { - return; - } - if (c == '.') { - dots++; - } - } - - if (head != null && head.dots > dots) { - // We already have a closer match so ignore this one, no need to parse the domainName etc. - return; - } - - System.err.println("DOUBLE CHECK me! we do things differently now!"); - NSRecord re = (NSRecord) record; - final String domainName = re.getAdditionalName() - .toString(); - if (domainName == null) { - // Could not be parsed, ignore. - return; - } - - // We are only interested in preserving the nameservers which are the closest to our qName, so ensure - // we drop servers that have a smaller dots count. - if (head == null || head.dots < dots) { - count = 1; - head = new AuthoritativeNameServer(dots, recordName, domainName); - } - else if (head.dots == dots) { - AuthoritativeNameServer serverName = head; - while (serverName.next != null) { - serverName = serverName.next; - } - serverName.next = new AuthoritativeNameServer(dots, recordName, domainName); - count++; - } - } - - // Just walk the linked-list and mark the entry as removed when matched, so next lookup will need to process - // one node less. - AuthoritativeNameServer remove(String nsName) { - AuthoritativeNameServer serverName = head; - - while (serverName != null) { - if (!serverName.removed && serverName.nsName.equalsIgnoreCase(nsName)) { - serverName.removed = true; - return serverName; - } - serverName = serverName.next; - } - return null; - } - - int size() { - return count; - } - } - - - static final - class AuthoritativeNameServer { - final int dots; - final String nsName; - final String domainName; - - AuthoritativeNameServer next; - boolean removed; - - AuthoritativeNameServer(int dots, String domainName, String nsName) { - this.dots = dots; - this.nsName = nsName; - this.domainName = domainName; - } - - /** - * Returns {@code true} if its a root server. - */ - boolean isRootServer() { - return dots == 1; - } - - /** - * The domain for which the {@link AuthoritativeNameServer} is responsible. - */ - String domainName() { - return domainName; - } - } -} diff --git a/src/dorkbox/network/dns/resolver/DnsNameResolverException.java b/src/dorkbox/network/dns/resolver/DnsNameResolverException.java deleted file mode 100644 index 21b320f1..00000000 --- a/src/dorkbox/network/dns/resolver/DnsNameResolverException.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2015 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import java.net.InetSocketAddress; - -import dorkbox.network.dns.DnsQuestion; -import dorkbox.network.dns.records.DnsMessage; -import io.netty.util.internal.EmptyArrays; -import io.netty.util.internal.ObjectUtil; -import io.netty.util.internal.UnstableApi; - -/** - * A {@link RuntimeException} raised when {@link DnsResolver} failed to perform a successful query. - */ -@UnstableApi -public final -class DnsNameResolverException extends RuntimeException { - - private static final long serialVersionUID = -8826717909627131850L; - - private final InetSocketAddress remoteAddress; - private final DnsQuestion question; - - public - DnsNameResolverException(InetSocketAddress remoteAddress, DnsQuestion question, String message) { - super(message); - this.remoteAddress = validateRemoteAddress(remoteAddress); - this.question = validateQuestion(question); - } - - private static - InetSocketAddress validateRemoteAddress(InetSocketAddress remoteAddress) { - return ObjectUtil.checkNotNull(remoteAddress, "remoteAddress"); - } - - private static - DnsQuestion validateQuestion(DnsQuestion question) { - return ObjectUtil.checkNotNull(question, "question"); - } - - public - DnsNameResolverException(InetSocketAddress remoteAddress, DnsQuestion question, String message, Throwable cause) { - super(message, cause); - this.remoteAddress = validateRemoteAddress(remoteAddress); - this.question = validateQuestion(question); - } - - /** - * Returns the {@link InetSocketAddress} of the DNS query that has failed. - */ - public - InetSocketAddress remoteAddress() { - return remoteAddress; - } - - /** - * Returns the {@link DnsQuestion} of the DNS query that has failed. - */ - public - DnsMessage question() { - return question; - } - - @Override - public - Throwable fillInStackTrace() { - setStackTrace(EmptyArrays.EMPTY_STACK_TRACE); - return this; - } -} diff --git a/src/dorkbox/network/dns/resolver/DnsNameResolverListResolverContext.java b/src/dorkbox/network/dns/resolver/DnsNameResolverListResolverContext.java deleted file mode 100644 index 2d572c5e..00000000 --- a/src/dorkbox/network/dns/resolver/DnsNameResolverListResolverContext.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2014 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.List; - -import dorkbox.network.dns.resolver.addressProvider.DnsServerAddressStream; -import dorkbox.network.dns.resolver.cache.DnsCache; -import dorkbox.network.dns.resolver.cache.DnsCacheEntry; -import io.netty.util.concurrent.Promise; - -/** - * - */ -final -class DnsNameResolverListResolverContext extends DnsNameResolverContext> { - DnsNameResolverListResolverContext(DnsNameResolver parent, - String hostname, - DnsCache resolveCache, - DnsServerAddressStream nameServerAddrs) { - super(parent, hostname, resolveCache, nameServerAddrs); - } - - @Override - DnsNameResolverContext> newResolverContext(DnsNameResolver parent, - String hostname, - DnsCache resolveCache, - DnsServerAddressStream nameServerAddrs) { - return new DnsNameResolverListResolverContext(parent, hostname, resolveCache, nameServerAddrs); - } - - @Override - boolean finishResolve(Class addressType, - List resolvedEntries, - Promise> promise) { - - List result = null; - final int numEntries = resolvedEntries.size(); - for (int i = 0; i < numEntries; i++) { - final InetAddress a = resolvedEntries.get(i).address(); - if (addressType.isInstance(a)) { - if (result == null) { - result = new ArrayList(numEntries); - } - result.add(a); - } - } - - if (result != null) { - promise.trySuccess(result); - return true; - } - return false; - } -} diff --git a/src/dorkbox/network/dns/resolver/DnsNameResolverResponseHandler.java b/src/dorkbox/network/dns/resolver/DnsNameResolverResponseHandler.java deleted file mode 100644 index 0051ff1e..00000000 --- a/src/dorkbox/network/dns/resolver/DnsNameResolverResponseHandler.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2014 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import dorkbox.network.dns.clientHandlers.DnsResponse; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.util.concurrent.Promise; - -final -class DnsNameResolverResponseHandler extends ChannelInboundHandlerAdapter { - - private DnsNameResolver dnsNameResolver; - private final Promise channelActivePromise; - - DnsNameResolverResponseHandler(final DnsNameResolver dnsNameResolver, Promise channelActivePromise) { - this.dnsNameResolver = dnsNameResolver; - this.channelActivePromise = channelActivePromise; - } - - @Override - public - void channelActive(ChannelHandlerContext ctx) throws Exception { - super.channelActive(ctx); - channelActivePromise.setSuccess(ctx.channel()); - } - - @Override - public - void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - final DnsResponse response = (DnsResponse) msg; - - final int queryId = response.getHeader().getID(); - - if (DnsNameResolver.logger.isDebugEnabled()) { - DnsNameResolver.logger.debug("{} RECEIVED: [{}: {}], {}", dnsNameResolver.ch, queryId, response.sender(), response); - } - - final DnsQueryContext qCtx = dnsNameResolver.queryContextManager.get(response.sender(), queryId); - if (qCtx == null) { - DnsNameResolver.logger.warn("{} Received a DNS response with an unknown ID: {}", dnsNameResolver.ch, queryId); - return; - } - - qCtx.finish(response); - } - - @Override - public - void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - DnsNameResolver.logger.warn("{} Unexpected exception: ", dnsNameResolver.ch, cause); - } -} diff --git a/src/dorkbox/network/dns/resolver/DnsNameResolverSingleResolverContext.java b/src/dorkbox/network/dns/resolver/DnsNameResolverSingleResolverContext.java deleted file mode 100644 index dd4b840e..00000000 --- a/src/dorkbox/network/dns/resolver/DnsNameResolverSingleResolverContext.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2014 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import java.net.InetAddress; -import java.util.List; - -import dorkbox.network.dns.resolver.addressProvider.DnsServerAddressStream; -import dorkbox.network.dns.resolver.cache.DnsCache; -import dorkbox.network.dns.resolver.cache.DnsCacheEntry; -import io.netty.util.concurrent.Promise; - -/** - * - */ -@SuppressWarnings("ForLoopReplaceableByForEach") -final -class DnsNameResolverSingleResolverContext extends DnsNameResolverContext { - DnsNameResolverSingleResolverContext(DnsNameResolver parent, - String hostname, - DnsCache resolveCache, - DnsServerAddressStream nameServerAddrs) { - super(parent, hostname, resolveCache, nameServerAddrs); - } - - @Override - boolean finishResolve(Class addressType, List resolvedEntries, Promise promise) { - - final int numEntries = resolvedEntries.size(); - - for (int i = 0; i < numEntries; i++) { - final InetAddress a = resolvedEntries.get(i).address(); - if (addressType.isInstance(a)) { - DnsNameResolver.trySuccess(promise, a); - return true; - } - } - - return false; - } - - @Override - DnsNameResolverContext newResolverContext(DnsNameResolver parent, - String hostname, - DnsCache resolveCache, - DnsServerAddressStream nameServerAddrs) { - return new DnsNameResolverSingleResolverContext(parent, hostname, resolveCache, nameServerAddrs); - } -} diff --git a/src/dorkbox/network/dns/resolver/DnsQueryContext.java b/src/dorkbox/network/dns/resolver/DnsQueryContext.java deleted file mode 100644 index eee0525f..00000000 --- a/src/dorkbox/network/dns/resolver/DnsQueryContext.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright 2014 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import static io.netty.util.internal.ObjectUtil.checkNotNull; - -import java.net.InetSocketAddress; -import java.util.concurrent.TimeUnit; - -import dorkbox.network.dns.DnsQuestion; -import dorkbox.network.dns.clientHandlers.DnsResponse; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.records.DnsRecord; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelPromise; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; -import io.netty.util.concurrent.Promise; -import io.netty.util.concurrent.ScheduledFuture; -import io.netty.util.internal.logging.InternalLogger; -import io.netty.util.internal.logging.InternalLoggerFactory; - -final -class DnsQueryContext { - - private static final InternalLogger logger = InternalLoggerFactory.getInstance(DnsQueryContext.class); - - private final DnsNameResolver parent; - private final Promise promise; - private final int id; - private final DnsQuestion question; - - private final InetSocketAddress nameServerAddr; - - private volatile ScheduledFuture timeoutFuture; - - DnsQueryContext(DnsNameResolver parent, - InetSocketAddress nameServerAddr, - DnsQuestion question, - Promise promise) { - - this.parent = checkNotNull(parent, "parent"); - this.nameServerAddr = checkNotNull(nameServerAddr, "nameServerAddr"); - this.question = checkNotNull(question, "question"); - this.promise = checkNotNull(promise, "promise"); - - id = parent.queryContextManager.add(this); - - question.init(id, nameServerAddr); - } - - void query(ChannelPromise writePromise) { - final DnsQuestion question = question(); - final InetSocketAddress nameServerAddr = nameServerAddr(); - - if (logger.isDebugEnabled()) { - logger.debug("{} WRITE: [{}: {}], {}", parent.ch, id, nameServerAddr, question); - } - - sendQuery(question, writePromise); - } - - InetSocketAddress nameServerAddr() { - return nameServerAddr; - } - - DnsQuestion question() { - return question; - } - - private - void sendQuery(final DnsQuestion query, final ChannelPromise writePromise) { - if (parent.channelFuture.isDone()) { - writeQuery(query, writePromise); - } - else { - parent.channelFuture.addListener(new GenericFutureListener>() { - @Override - public - void operationComplete(Future future) throws Exception { - if (future.isSuccess()) { - writeQuery(query, writePromise); - } - else { - Throwable cause = future.cause(); - promise.tryFailure(cause); - writePromise.setFailure(cause); - } - } - }); - } - } - - private - void writeQuery(final DnsQuestion query, final ChannelPromise writePromise) { - final ChannelFuture writeFuture = parent.ch.writeAndFlush(query, writePromise); - if (writeFuture.isDone()) { - onQueryWriteCompletion(writeFuture); - } - else { - writeFuture.addListener(new ChannelFutureListener() { - @Override - public - void operationComplete(ChannelFuture future) throws Exception { - onQueryWriteCompletion(writeFuture); - } - }); - } - } - - private - void onQueryWriteCompletion(ChannelFuture writeFuture) { - if (!writeFuture.isSuccess()) { - writeFuture.cause() - .printStackTrace(); - setFailure("failed to send a query", writeFuture.cause()); - return; - } - - // Schedule a query timeout task if necessary. - final long queryTimeoutMillis = parent.queryTimeoutMillis(); - if (queryTimeoutMillis > 0) { - timeoutFuture = parent.ch.eventLoop() - .schedule(new Runnable() { - @Override - public - void run() { - if (promise.isDone()) { - // Received a response before the query times out. - return; - } - - setFailure("query timed out after " + queryTimeoutMillis + " milliseconds", null); - } - }, queryTimeoutMillis, TimeUnit.MILLISECONDS); - } - } - - private - void setFailure(String message, Throwable cause) { - final InetSocketAddress nameServerAddr = nameServerAddr(); - parent.queryContextManager.remove(nameServerAddr, id); - - final StringBuilder buf = new StringBuilder(message.length() + 64); - buf.append('[') - .append(nameServerAddr) - .append("] ") - .append(message) - .append(" (no stack trace available)"); - - final DnsNameResolverException e; - if (cause != null) { - e = new DnsNameResolverException(nameServerAddr, question(), buf.toString(), cause); - } - else { - e = new DnsNameResolverException(nameServerAddr, question(), buf.toString()); - } - - promise.tryFailure(e); - } - - void finish(DnsResponse response) { - - try { - DnsRecord[] sectionArray = response.getSectionArray(DnsSection.QUESTION); - if (sectionArray.length != 1) { - logger.warn("Received a DNS response with invalid number of questions: {}", response); - return; - } - - DnsRecord[] questionArray = question.getSectionArray(DnsSection.QUESTION); - if (questionArray.length != 1) { - logger.warn("Received a DNS response with invalid number of query questions: {}", response); - return; - } - - - if (!questionArray[0].equals(sectionArray[0])) { - logger.warn("Received a mismatching DNS response: {}", response); - return; - } - - setSuccess(response); - } finally { - if (question.isResolveQuestion()) { - // for resolve questions (always A/AAAA), we convert the answer into InetAddress, however with OTHER TYPES, we pass - // back the result to the user, and if we release it, all of the content will be cleared. - response.release(); - } - } - } - - private - void setSuccess(DnsResponse response) { - parent.queryContextManager.remove(nameServerAddr(), id); - - // Cancel the timeout task. - final ScheduledFuture timeoutFuture = this.timeoutFuture; - if (timeoutFuture != null) { - timeoutFuture.cancel(false); - } - - Promise promise = this.promise; - if (promise.setUncancellable()) { - response.retain(); - // response now has a refCnt = 2 - if (!promise.trySuccess(response)) { // question is used here! - // We failed to notify the promise as it was failed before, thus we need to release the envelope - response.release(); - } - - response.release(); - } - } -} diff --git a/src/dorkbox/network/dns/resolver/DnsQueryContextManager.java b/src/dorkbox/network/dns/resolver/DnsQueryContextManager.java deleted file mode 100644 index f62516a0..00000000 --- a/src/dorkbox/network/dns/resolver/DnsQueryContextManager.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2015 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.UnknownHostException; -import java.util.HashMap; -import java.util.Map; - -import io.netty.util.NetUtil; -import io.netty.util.collection.IntObjectHashMap; -import io.netty.util.collection.IntObjectMap; -import io.netty.util.internal.PlatformDependent; - -final -class DnsQueryContextManager { - - /** - * A map whose key is the DNS server address and value is the map of the DNS query ID and its corresponding {@link DnsQueryContext}. - */ - final Map> map = new HashMap>(); - - int add(DnsQueryContext queryContext) { - final IntObjectMap contexts = getOrCreateContextMap(queryContext.nameServerAddr()); - - int id = PlatformDependent.threadLocalRandom() - .nextInt(65536 - 1) + 1; - final int maxTries = 65535 << 1; - int tries = 0; - - synchronized (contexts) { - for (; ; ) { - if (!contexts.containsKey(id)) { - contexts.put(id, queryContext); - return id; - } - - id = id + 1 & 0xFFFF; - - if (++tries >= maxTries) { - throw new IllegalStateException("query ID space exhausted: " + queryContext.question()); - } - } - } - } - - private - IntObjectMap getOrCreateContextMap(InetSocketAddress nameServerAddr) { - synchronized (map) { - final IntObjectMap contexts = map.get(nameServerAddr); - if (contexts != null) { - return contexts; - } - - final IntObjectMap newContexts = new IntObjectHashMap(); - final InetAddress a = nameServerAddr.getAddress(); - final int port = nameServerAddr.getPort(); - map.put(nameServerAddr, newContexts); - - if (a instanceof Inet4Address) { - // Also add the mapping for the IPv4-compatible IPv6 address. - final Inet4Address a4 = (Inet4Address) a; - if (a4.isLoopbackAddress()) { - map.put(new InetSocketAddress(NetUtil.LOCALHOST6, port), newContexts); - } - else { - map.put(new InetSocketAddress(toCompactAddress(a4), port), newContexts); - } - } - else if (a instanceof Inet6Address) { - // Also add the mapping for the IPv4 address if this IPv6 address is compatible. - final Inet6Address a6 = (Inet6Address) a; - if (a6.isLoopbackAddress()) { - map.put(new InetSocketAddress(NetUtil.LOCALHOST4, port), newContexts); - } - else if (a6.isIPv4CompatibleAddress()) { - map.put(new InetSocketAddress(toIPv4Address(a6), port), newContexts); - } - } - - return newContexts; - } - } - - private static - Inet6Address toCompactAddress(Inet4Address a4) { - byte[] b4 = a4.getAddress(); - byte[] b6 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, b4[0], b4[1], b4[2], b4[3]}; - try { - return (Inet6Address) InetAddress.getByAddress(b6); - } catch (UnknownHostException e) { - throw new Error(e); - } - } - - private static - Inet4Address toIPv4Address(Inet6Address a6) { - byte[] b6 = a6.getAddress(); - byte[] b4 = {b6[12], b6[13], b6[14], b6[15]}; - try { - return (Inet4Address) InetAddress.getByAddress(b4); - } catch (UnknownHostException e) { - throw new Error(e); - } - } - - DnsQueryContext get(InetSocketAddress nameServerAddr, int id) { - final IntObjectMap contexts = getContextMap(nameServerAddr); - final DnsQueryContext qCtx; - if (contexts != null) { - synchronized (contexts) { - qCtx = contexts.get(id); - } - } - else { - qCtx = null; - } - - return qCtx; - } - - private - IntObjectMap getContextMap(InetSocketAddress nameServerAddr) { - synchronized (map) { - return map.get(nameServerAddr); - } - } - - DnsQueryContext remove(InetSocketAddress nameServerAddr, int id) { - final IntObjectMap contexts = getContextMap(nameServerAddr); - if (contexts == null) { - return null; - } - - synchronized (contexts) { - return contexts.remove(id); - } - } -} diff --git a/src/dorkbox/network/dns/resolver/DnsQueryLifecycleObserver.java b/src/dorkbox/network/dns/resolver/DnsQueryLifecycleObserver.java deleted file mode 100644 index d16cacab..00000000 --- a/src/dorkbox/network/dns/resolver/DnsQueryLifecycleObserver.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import java.net.InetSocketAddress; -import java.util.List; - -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.records.DnsMessage; -import io.netty.channel.ChannelFuture; -import io.netty.util.internal.UnstableApi; - -/** - * This interface provides visibility into individual DNS queries. The lifecycle of an objects is as follows: - *

    - *
  1. Object creation
  2. - *
  3. {@link #queryCancelled(int)}
  4. - *
- * OR - *
    - *
  1. Object creation
  2. - *
  3. {@link #queryWritten(InetSocketAddress, ChannelFuture)}
  4. - *
  5. {@link #queryRedirected(List)} or {@link #queryCNAMEd(DnsQuestion)} or - * {@link #queryNoAnswer(int)} or {@link #queryCancelled(int)} or - * {@link #queryFailed(Throwable)} or {@link #querySucceed()}
  6. - *
- *

- * This interface can be used to track metrics for individual DNS servers. Methods which may lead to another DNS query - * return an object of type {@link DnsQueryLifecycleObserver}. Implementations may use this to build a query tree to - * understand the "sub queries" generated by a single query. - */ -@UnstableApi -public -interface DnsQueryLifecycleObserver { - /** - * The query has been written. - * - * @param dnsServerAddress The DNS server address which the query was sent to. - * @param future The future which represents the status of the write operation for the DNS query. - */ - void queryWritten(InetSocketAddress dnsServerAddress, ChannelFuture future); - - /** - * The query may have been written but it was cancelled at some point. - * - * @param queriesRemaining The number of queries remaining. - */ - void queryCancelled(int queriesRemaining); - - /** - * The query has been redirected to another list of DNS servers. - * - * @param nameServers The name servers the query has been redirected to. - * - * @return An observer for the new query which we may issue. - */ - DnsQueryLifecycleObserver queryRedirected(List nameServers); - - /** - * The query returned a CNAME which we may attempt to follow with a new query. - *

- * Note that multiple queries may be encountering a CNAME. For example a if both {@link DnsRecordType#AAAA} and - * {@link DnsRecordType#A} are supported we may query for both. - * - * @param cnameQuestion the question we would use if we issue a new query. - * - * @return An observer for the new query which we may issue. - */ - DnsQueryLifecycleObserver queryCNAMEd(DnsMessage cnameQuestion); - - /** - * The response to the query didn't provide the expected response code, but it didn't return - * {@link DnsResponseCode#NXDOMAIN} so we may try to query again. - * - * @param code the unexpected response code. - * - * @return An observer for the new query which we may issue. - */ - DnsQueryLifecycleObserver queryNoAnswer(int code); - - /** - * The following criteria are possible: - *

    - *
  • IO Error
  • - *
  • Server responded with an invalid DNS response
  • - *
  • Server responded with a valid DNS response, but it didn't progress the resolution
  • - *
- * - * @param cause The cause which for the failure. - */ - void queryFailed(Throwable cause); - - /** - * The query received the expected results. - */ - void querySucceed(); -} diff --git a/src/dorkbox/network/dns/resolver/DnsQueryLifecycleObserverFactory.java b/src/dorkbox/network/dns/resolver/DnsQueryLifecycleObserverFactory.java deleted file mode 100644 index 54a7f405..00000000 --- a/src/dorkbox/network/dns/resolver/DnsQueryLifecycleObserverFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import dorkbox.network.dns.records.DnsMessage; -import io.netty.util.internal.UnstableApi; - -/** - * Used to generate new instances of {@link DnsQueryLifecycleObserver}. - */ -@UnstableApi -public -interface DnsQueryLifecycleObserverFactory { - /** - * Create a new instance of a {@link DnsQueryLifecycleObserver}. This will be called at the start of a new query. - * - * @param question The question being asked. - * - * @return a new instance of a {@link DnsQueryLifecycleObserver}. - */ - DnsQueryLifecycleObserver newDnsQueryLifecycleObserver(DnsMessage question); -} diff --git a/src/dorkbox/network/dns/resolver/InetNameGroupResolver.java b/src/dorkbox/network/dns/resolver/InetNameGroupResolver.java deleted file mode 100644 index 2dd674a6..00000000 --- a/src/dorkbox/network/dns/resolver/InetNameGroupResolver.java +++ /dev/null @@ -1,39 +0,0 @@ -package dorkbox.network.dns.resolver; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.util.List; - -import io.netty.resolver.AddressResolver; -import io.netty.resolver.SimpleNameResolver; -import io.netty.util.concurrent.EventExecutor; - -public abstract class InetNameGroupResolver extends SimpleNameResolver> { - private volatile AddressResolver addressResolver; - - /** - * @param executor the {@link EventExecutor} which is used to notify the listeners of the {@link Future} returned - * by {@link #resolve(String)} - */ - protected - InetNameGroupResolver(EventExecutor executor) { - super(executor); - } - - /** - * Return a {@link AddressResolver} that will use this name resolver underneath. - * It's cached internally, so the same instance is always returned. - */ - public AddressResolver asAddressResolver() { - AddressResolver result = addressResolver; - if (result == null) { - synchronized (this) { - result = addressResolver; - if (result == null) { - addressResolver = result = new InetSocketAddressGroupResolver(executor(), this); - } - } - } - return result; - } -} diff --git a/src/dorkbox/network/dns/resolver/InetSocketAddressGroupResolver.java b/src/dorkbox/network/dns/resolver/InetSocketAddressGroupResolver.java deleted file mode 100644 index bc15364b..00000000 --- a/src/dorkbox/network/dns/resolver/InetSocketAddressGroupResolver.java +++ /dev/null @@ -1,86 +0,0 @@ -package dorkbox.network.dns.resolver; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.List; - -import io.netty.resolver.AbstractAddressResolver; -import io.netty.resolver.NameResolver; -import io.netty.util.concurrent.EventExecutor; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; -import io.netty.util.concurrent.Promise; - -public class InetSocketAddressGroupResolver extends AbstractAddressResolver { - - final NameResolver> nameResolver; - - /** - * @param executor the {@link EventExecutor} which is used to notify the listeners of the {@link Future} returned - * by {@link #resolve(java.net.SocketAddress)} - * @param nameResolver the {@link NameResolver} used for name resolution - */ - public - InetSocketAddressGroupResolver(EventExecutor executor, NameResolver> nameResolver) { - super(executor, InetSocketAddress.class); - this.nameResolver = nameResolver; - } - - @Override - protected boolean doIsResolved(InetSocketAddress address) { - return !address.isUnresolved(); - } - - @Override - protected void doResolve(final InetSocketAddress unresolvedAddress, final Promise promise) throws Exception { - // Note that InetSocketAddress.getHostName() will never incur a reverse lookup here, - // because an unresolved address always has a host name. - nameResolver.resolve(unresolvedAddress.getHostName()) - .addListener(new FutureListener>() { - @Override - public void operationComplete(Future> future) throws Exception { - if (future.isSuccess()) { - ArrayList arrayList = new ArrayList(); - List now = future.getNow(); - for (InetAddress inetAddress : now) { - arrayList.add(new InetSocketAddress(inetAddress, unresolvedAddress.getPort())); - } - // promise.setSuccess(arrayList); - } else { - promise.setFailure(future.cause()); - } - } - }); - } - - @Override - protected void doResolveAll(final InetSocketAddress unresolvedAddress, final Promise> promise) throws Exception { - // Note that InetSocketAddress.getHostName() will never incur a reverse lookup here, - // because an unresolved address always has a host name. - nameResolver.resolveAll(unresolvedAddress.getHostName()) - .addListener(new FutureListener>>() { - @Override - public void operationComplete(Future>> future) throws Exception { - if (future.isSuccess()) { - List> inetAddresseses = future.getNow(); - List socketAddresses = new ArrayList(inetAddresseses.size()); - for (List inetAddresses : inetAddresseses) { - for (InetAddress inetAddress : inetAddresses) { - socketAddresses.add(new InetSocketAddress(inetAddress, unresolvedAddress.getPort())); - } - } - - promise.setSuccess(socketAddresses); - } else { - promise.setFailure(future.cause()); - } - } - }); - } - - @Override - public void close() { - nameResolver.close(); - } -} diff --git a/src/dorkbox/network/dns/resolver/InflightNameResolver.java b/src/dorkbox/network/dns/resolver/InflightNameResolver.java deleted file mode 100644 index 659e1a5c..00000000 --- a/src/dorkbox/network/dns/resolver/InflightNameResolver.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2016 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import static io.netty.util.internal.ObjectUtil.checkNotNull; - -import java.util.List; -import java.util.concurrent.ConcurrentMap; - -import io.netty.resolver.NameResolver; -import io.netty.util.concurrent.EventExecutor; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; -import io.netty.util.concurrent.Promise; -import io.netty.util.internal.StringUtil; - -// FIXME(trustin): Find a better name and move it to the 'resolver' module. -public final -class InflightNameResolver implements NameResolver { - - private final EventExecutor executor; - private final NameResolver delegate; - private final ConcurrentMap> resolvesInProgress; - private final ConcurrentMap>> resolveAllsInProgress; - - InflightNameResolver(EventExecutor executor, - NameResolver delegate, - ConcurrentMap> resolvesInProgress, - ConcurrentMap>> resolveAllsInProgress) { - - this.executor = checkNotNull(executor, "executor"); - this.delegate = checkNotNull(delegate, "delegate"); - this.resolvesInProgress = checkNotNull(resolvesInProgress, "resolvesInProgress"); - this.resolveAllsInProgress = checkNotNull(resolveAllsInProgress, "resolveAllsInProgress"); - } - - @Override - public - Future resolve(String inetHost) { - return resolve(inetHost, executor.newPromise()); - } - - @Override - public - Promise resolve(String inetHost, Promise promise) { - return resolve(resolvesInProgress, inetHost, promise, false); - } - - @Override - public - Future> resolveAll(String inetHost) { - return resolveAll(inetHost, executor.>newPromise()); - } - - @Override - public - Promise> resolveAll(String inetHost, Promise> promise) { - return resolve(resolveAllsInProgress, inetHost, promise, true); - } - - @Override - public - void close() { - delegate.close(); - } - - private - Promise resolve(final ConcurrentMap> resolveMap, - final String inetHost, - final Promise promise, - boolean resolveAll) { - - final Promise earlyPromise = resolveMap.putIfAbsent(inetHost, promise); - if (earlyPromise != null) { - // Name resolution for the specified inetHost is in progress already. - if (earlyPromise.isDone()) { - transferResult(earlyPromise, promise); - } - else { - earlyPromise.addListener(new FutureListener() { - @Override - public - void operationComplete(Future f) throws Exception { - transferResult(f, promise); - } - }); - } - } - else { - try { - if (resolveAll) { - @SuppressWarnings("unchecked") - final Promise> castPromise = (Promise>) promise; // U is List - delegate.resolveAll(inetHost, castPromise); - } - else { - @SuppressWarnings("unchecked") - final Promise castPromise = (Promise) promise; // U is T - delegate.resolve(inetHost, castPromise); - } - } finally { - if (promise.isDone()) { - resolveMap.remove(inetHost); - } - else { - promise.addListener(new FutureListener() { - @Override - public - void operationComplete(Future f) throws Exception { - resolveMap.remove(inetHost); - } - }); - } - } - } - - return promise; - } - - private static - void transferResult(Future src, Promise dst) { - if (src.isSuccess()) { - dst.trySuccess(src.getNow()); - } - else { - dst.tryFailure(src.cause()); - } - } - - @Override - public - String toString() { - return StringUtil.simpleClassName(this) + '(' + delegate + ')'; - } -} diff --git a/src/dorkbox/network/dns/resolver/MultiDnsServerAddressStreamProvider.java b/src/dorkbox/network/dns/resolver/MultiDnsServerAddressStreamProvider.java deleted file mode 100644 index a025260f..00000000 --- a/src/dorkbox/network/dns/resolver/MultiDnsServerAddressStreamProvider.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import java.util.List; - -import dorkbox.network.dns.resolver.addressProvider.DnsServerAddressStream; -import dorkbox.network.dns.resolver.addressProvider.DnsServerAddressStreamProvider; -import io.netty.util.internal.UnstableApi; - -/** - * A {@link DnsServerAddressStreamProvider} which iterates through a collection of - * {@link DnsServerAddressStreamProvider} until the first non-{@code null} result is found. - */ -@UnstableApi -public final -class MultiDnsServerAddressStreamProvider implements DnsServerAddressStreamProvider { - private final DnsServerAddressStreamProvider[] providers; - - /** - * Create a new instance. - * - * @param providers The providers to use for DNS resolution. They will be queried in order. - */ - public - MultiDnsServerAddressStreamProvider(List providers) { - this.providers = providers.toArray(new DnsServerAddressStreamProvider[0]); - } - - /** - * Create a new instance. - * - * @param providers The providers to use for DNS resolution. They will be queried in order. - */ - public - MultiDnsServerAddressStreamProvider(DnsServerAddressStreamProvider... providers) { - this.providers = providers.clone(); - } - - @Override - public - DnsServerAddressStream nameServerAddressStream(String hostname) { - for (DnsServerAddressStreamProvider provider : providers) { - DnsServerAddressStream stream = provider.nameServerAddressStream(hostname); - if (stream != null) { - return stream; - } - } - return null; - } -} diff --git a/src/dorkbox/network/dns/resolver/NoopDnsQueryLifecycleObserver.java b/src/dorkbox/network/dns/resolver/NoopDnsQueryLifecycleObserver.java deleted file mode 100644 index 0e99df5b..00000000 --- a/src/dorkbox/network/dns/resolver/NoopDnsQueryLifecycleObserver.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import java.net.InetSocketAddress; -import java.util.List; - -import dorkbox.network.dns.records.DnsMessage; -import io.netty.channel.ChannelFuture; - -final -class NoopDnsQueryLifecycleObserver implements DnsQueryLifecycleObserver { - static final NoopDnsQueryLifecycleObserver INSTANCE = new NoopDnsQueryLifecycleObserver(); - - private - NoopDnsQueryLifecycleObserver() { - } - - @Override - public - void queryWritten(InetSocketAddress dnsServerAddress, ChannelFuture future) { - } - - @Override - public - void queryCancelled(int queriesRemaining) { - } - - @Override - public - DnsQueryLifecycleObserver queryRedirected(List nameServers) { - return this; - } - - @Override - public - DnsQueryLifecycleObserver queryCNAMEd(DnsMessage cnameQuestion) { - return this; - } - - @Override - public - DnsQueryLifecycleObserver queryNoAnswer(int code) { - return this; - } - - @Override - public - void queryFailed(Throwable cause) { - } - - @Override - public - void querySucceed() { - } -} diff --git a/src/dorkbox/network/dns/resolver/NoopDnsQueryLifecycleObserverFactory.java b/src/dorkbox/network/dns/resolver/NoopDnsQueryLifecycleObserverFactory.java deleted file mode 100644 index 0ab8d4c7..00000000 --- a/src/dorkbox/network/dns/resolver/NoopDnsQueryLifecycleObserverFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import dorkbox.network.dns.records.DnsMessage; -import io.netty.util.internal.UnstableApi; - -@UnstableApi -public final -class NoopDnsQueryLifecycleObserverFactory implements DnsQueryLifecycleObserverFactory { - public static final NoopDnsQueryLifecycleObserverFactory INSTANCE = new NoopDnsQueryLifecycleObserverFactory(); - - private - NoopDnsQueryLifecycleObserverFactory() { - } - - @Override - public - DnsQueryLifecycleObserver newDnsQueryLifecycleObserver(DnsMessage question) { - return NoopDnsQueryLifecycleObserver.INSTANCE; - } -} diff --git a/src/dorkbox/network/dns/resolver/TraceDnsQueryLifeCycleObserverFactory.java b/src/dorkbox/network/dns/resolver/TraceDnsQueryLifeCycleObserverFactory.java deleted file mode 100644 index 0a8dbdc6..00000000 --- a/src/dorkbox/network/dns/resolver/TraceDnsQueryLifeCycleObserverFactory.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import static io.netty.util.internal.ObjectUtil.checkNotNull; - -import dorkbox.network.dns.records.DnsMessage; -import io.netty.util.internal.logging.InternalLogLevel; -import io.netty.util.internal.logging.InternalLogger; -import io.netty.util.internal.logging.InternalLoggerFactory; - -final -class TraceDnsQueryLifeCycleObserverFactory implements DnsQueryLifecycleObserverFactory { - private static final InternalLogger DEFAULT_LOGGER = InternalLoggerFactory.getInstance(TraceDnsQueryLifeCycleObserverFactory.class); - private static final InternalLogLevel DEFAULT_LEVEL = InternalLogLevel.DEBUG; - private final InternalLogger logger; - private final InternalLogLevel level; - - TraceDnsQueryLifeCycleObserverFactory() { - this(DEFAULT_LOGGER, DEFAULT_LEVEL); - } - - TraceDnsQueryLifeCycleObserverFactory(InternalLogger logger, InternalLogLevel level) { - this.logger = checkNotNull(logger, "logger"); - this.level = checkNotNull(level, "level"); - } - - @Override - public - DnsQueryLifecycleObserver newDnsQueryLifecycleObserver(DnsMessage question) { - return new TraceDnsQueryLifecycleObserver(question, logger, level); - } -} diff --git a/src/dorkbox/network/dns/resolver/TraceDnsQueryLifecycleObserver.java b/src/dorkbox/network/dns/resolver/TraceDnsQueryLifecycleObserver.java deleted file mode 100644 index b87882ba..00000000 --- a/src/dorkbox/network/dns/resolver/TraceDnsQueryLifecycleObserver.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver; - -import static io.netty.util.internal.ObjectUtil.checkNotNull; - -import java.net.InetSocketAddress; -import java.util.List; - -import dorkbox.network.dns.records.DnsMessage; -import io.netty.channel.ChannelFuture; -import io.netty.util.internal.logging.InternalLogLevel; -import io.netty.util.internal.logging.InternalLogger; - -final -class TraceDnsQueryLifecycleObserver implements DnsQueryLifecycleObserver { - private final InternalLogger logger; - private final InternalLogLevel level; - private final DnsMessage question; - private InetSocketAddress dnsServerAddress; - - TraceDnsQueryLifecycleObserver(DnsMessage question, InternalLogger logger, InternalLogLevel level) { - this.question = checkNotNull(question, "question"); - this.logger = checkNotNull(logger, "logger"); - this.level = checkNotNull(level, "level"); - } - - @Override - public - void queryWritten(InetSocketAddress dnsServerAddress, ChannelFuture future) { - this.dnsServerAddress = dnsServerAddress; - } - - @Override - public - void queryCancelled(int queriesRemaining) { - if (dnsServerAddress != null) { - logger.log(level, "from {} : {} cancelled with {} queries remaining", dnsServerAddress, question, queriesRemaining); - } - else { - logger.log(level, "{} query never written and cancelled with {} queries remaining", question, queriesRemaining); - } - } - - @Override - public - DnsQueryLifecycleObserver queryRedirected(List nameServers) { - logger.log(level, "from {} : {} redirected", dnsServerAddress, question); - return this; - } - - @Override - public - DnsQueryLifecycleObserver queryCNAMEd(DnsMessage cnameQuestion) { - logger.log(level, "from {} : {} CNAME question {}", dnsServerAddress, question, cnameQuestion); - return this; - } - - @Override - public - DnsQueryLifecycleObserver queryNoAnswer(int code) { - logger.log(level, "from {} : {} no answer {}", dnsServerAddress, question, code); - return this; - } - - @Override - public - void queryFailed(Throwable cause) { - if (dnsServerAddress != null) { - logger.log(level, "from {} : {} failure", dnsServerAddress, question, cause); - } - else { - logger.log(level, "{} query never written and failed", question, cause); - } - } - - @Override - public - void querySucceed() { - } -} diff --git a/src/dorkbox/network/dns/resolver/addressProvider/DefaultDnsServerAddressStreamProvider.java b/src/dorkbox/network/dns/resolver/addressProvider/DefaultDnsServerAddressStreamProvider.java deleted file mode 100644 index 0af2c4a5..00000000 --- a/src/dorkbox/network/dns/resolver/addressProvider/DefaultDnsServerAddressStreamProvider.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.addressProvider; - -import java.lang.reflect.Method; -import java.net.InetSocketAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Hashtable; -import java.util.List; - -import javax.naming.Context; -import javax.naming.NamingException; -import javax.naming.directory.DirContext; -import javax.naming.directory.InitialDirContext; - -import io.netty.util.internal.SocketUtils; -import io.netty.util.internal.UnstableApi; -import io.netty.util.internal.logging.InternalLogger; -import io.netty.util.internal.logging.InternalLoggerFactory; - -/** - * A {@link DnsServerAddressStreamProvider} which will use predefined default DNS servers to use for DNS resolution. - * These defaults do not respect your host's machines defaults. - *

- * This may use the JDK's blocking DNS resolution to bootstrap the default DNS server addresses. - */ -@UnstableApi -public final -class DefaultDnsServerAddressStreamProvider implements DnsServerAddressStreamProvider { - - private static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultDnsServerAddressStreamProvider.class); - public static final DefaultDnsServerAddressStreamProvider INSTANCE = new DefaultDnsServerAddressStreamProvider(); - - private static final List DEFAULT_NAME_SERVER_LIST; - private static final InetSocketAddress[] DEFAULT_NAME_SERVER_ARRAY; - private static final DnsServerAddresses DEFAULT_NAME_SERVERS; - - public static final int DNS_PORT = 53; - - static { - final List defaultNameServers = new ArrayList(2); - - // Using jndi-dns to obtain the default name servers. - // - // See: - // - http://docs.oracle.com/javase/8/docs/technotes/guides/jndi/jndi-dns.html - // - http://mail.openjdk.java.net/pipermail/net-dev/2017-March/010695.html - Hashtable env = new Hashtable(); - env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory"); - env.put("java.naming.provider.url", "dns://"); - try { - DirContext ctx = new InitialDirContext(env); - String dnsUrls = (String) ctx.getEnvironment() - .get("java.naming.provider.url"); - String[] servers = dnsUrls.split(" "); - for (String server : servers) { - try { - defaultNameServers.add(SocketUtils.socketAddress(new URI(server).getHost(), DNS_PORT)); - } catch (URISyntaxException e) { - logger.debug("Skipping a malformed nameserver URI: {}", server, e); - } - } - } catch (NamingException ignore) { - // Will try reflection if this fails. - } - - if (defaultNameServers.isEmpty()) { - try { - Class configClass = Class.forName("sun.net.dns.ResolverConfiguration"); - Method open = configClass.getMethod("open"); - Method nameservers = configClass.getMethod("nameservers"); - Object instance = open.invoke(null); - - @SuppressWarnings("unchecked") - final List list = (List) nameservers.invoke(instance); - for (String a : list) { - if (a != null) { - defaultNameServers.add(new InetSocketAddress(SocketUtils.addressByName(a), DNS_PORT)); - } - } - } catch (Exception ignore) { - // Failed to get the system name server list via reflection. - // Will add the default name servers afterwards. - } - } - - if (!defaultNameServers.isEmpty()) { - if (logger.isDebugEnabled()) { - logger.debug("Default DNS servers: {} (sun.net.dns.ResolverConfiguration)", defaultNameServers); - } - } - else { - Collections.addAll(defaultNameServers, - SocketUtils.socketAddress("8.8.8.8", DNS_PORT), - SocketUtils.socketAddress("8.8.4.4", DNS_PORT)); - - if (logger.isWarnEnabled()) { - logger.warn("Default DNS servers: {} (Google Public DNS as a fallback)", defaultNameServers); - } - } - - DEFAULT_NAME_SERVER_LIST = Collections.unmodifiableList(defaultNameServers); - DEFAULT_NAME_SERVER_ARRAY = defaultNameServers.toArray(new InetSocketAddress[defaultNameServers.size()]); - DEFAULT_NAME_SERVERS = DnsServerAddresses.sequential(DEFAULT_NAME_SERVER_ARRAY); - } - - private - DefaultDnsServerAddressStreamProvider() { - } - - @Override - public - DnsServerAddressStream nameServerAddressStream(String hostname) { - return DEFAULT_NAME_SERVERS.stream(); - } - - /** - * Returns the list of the system DNS server addresses. If it failed to retrieve the list of the system DNS server - * addresses from the environment, it will return {@code "8.8.8.8"} and {@code "8.8.4.4"}, the addresses of the - * Google public DNS servers. - */ - public static - List defaultAddressList() { - return DEFAULT_NAME_SERVER_LIST; - } - - /** - * Returns the {@link DnsServerAddresses} that yields the system DNS server addresses sequentially. If it failed to - * retrieve the list of the system DNS server addresses from the environment, it will use {@code "8.8.8.8"} and - * {@code "8.8.4.4"}, the addresses of the Google public DNS servers. - *

- * This method has the same effect with the following code: - *

-     * DnsServerAddresses.sequential(DnsServerAddresses.defaultAddressList());
-     * 
- *

- */ - public static - DnsServerAddresses defaultAddresses() { - return DEFAULT_NAME_SERVERS; - } - - /** - * Get the array form of {@link #defaultAddressList()}. - * - * @return The array form of {@link #defaultAddressList()}. - */ - static - InetSocketAddress[] defaultAddressArray() { - return DEFAULT_NAME_SERVER_ARRAY.clone(); - } -} diff --git a/src/dorkbox/network/dns/resolver/addressProvider/DefaultDnsServerAddresses.java b/src/dorkbox/network/dns/resolver/addressProvider/DefaultDnsServerAddresses.java deleted file mode 100644 index c20b4796..00000000 --- a/src/dorkbox/network/dns/resolver/addressProvider/DefaultDnsServerAddresses.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2015 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.addressProvider; - -import java.net.InetSocketAddress; - -abstract -class DefaultDnsServerAddresses extends DnsServerAddresses { - - protected final InetSocketAddress[] addresses; - private final String strVal; - - DefaultDnsServerAddresses(String type, InetSocketAddress[] addresses) { - this.addresses = addresses; - - final StringBuilder buf = new StringBuilder(type.length() + 2 + addresses.length * 16); - buf.append(type) - .append('('); - - for (InetSocketAddress a : addresses) { - buf.append(a) - .append(", "); - } - - buf.setLength(buf.length() - 2); - buf.append(')'); - - strVal = buf.toString(); - } - - @Override - public - String toString() { - return strVal; - } -} diff --git a/src/dorkbox/network/dns/resolver/addressProvider/DnsServerAddressStream.java b/src/dorkbox/network/dns/resolver/addressProvider/DnsServerAddressStream.java deleted file mode 100644 index 1fb2fa08..00000000 --- a/src/dorkbox/network/dns/resolver/addressProvider/DnsServerAddressStream.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2015 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.addressProvider; - -import java.net.InetSocketAddress; - -import io.netty.util.internal.UnstableApi; - -/** - * An infinite stream of DNS server addresses. - */ -@UnstableApi -public -interface DnsServerAddressStream { - /** - * Retrieves the next DNS server address from the stream. - */ - InetSocketAddress next(); - - /** - * Get the number of times {@link #next()} will return a distinct element before repeating or terminating. - * - * @return the number of times {@link #next()} will return a distinct element before repeating or terminating. - */ - int size(); - - /** - * Duplicate this object. The result of this should be able to be independently iterated over via {@link #next()}. - *

- * Note that {@link #clone()} isn't used because it may make sense for some implementations to have the following - * relationship {@code x.duplicate() == x}. - * - * @return A duplicate of this object. - */ - DnsServerAddressStream duplicate(); -} diff --git a/src/dorkbox/network/dns/resolver/addressProvider/DnsServerAddressStreamProvider.java b/src/dorkbox/network/dns/resolver/addressProvider/DnsServerAddressStreamProvider.java deleted file mode 100644 index 42324461..00000000 --- a/src/dorkbox/network/dns/resolver/addressProvider/DnsServerAddressStreamProvider.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.addressProvider; - -import io.netty.util.internal.UnstableApi; - -/** - * Provides an opportunity to override which {@link DnsServerAddressStream} is used to resolve a specific hostname. - *

- * For example this can be used to represent /etc/resolv.conf and - * - * /etc/resolver. - */ -@UnstableApi -public -interface DnsServerAddressStreamProvider { - /** - * Ask this provider for the name servers to query for {@code hostname}. - * - * @param hostname The hostname for which to lookup the DNS server addressed to use. - * If this is the final {@link DnsServerAddressStreamProvider} to be queried then generally empty - * string or {@code '.'} correspond to the default {@link DnsServerAddressStream}. - * - * @return The {@link DnsServerAddressStream} which should be used to resolve {@code hostname}. - */ - DnsServerAddressStream nameServerAddressStream(String hostname); -} diff --git a/src/dorkbox/network/dns/resolver/addressProvider/DnsServerAddressStreamProviders.java b/src/dorkbox/network/dns/resolver/addressProvider/DnsServerAddressStreamProviders.java deleted file mode 100644 index ef4b510e..00000000 --- a/src/dorkbox/network/dns/resolver/addressProvider/DnsServerAddressStreamProviders.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.addressProvider; - -import io.netty.util.internal.UnstableApi; - -/** - * Utility methods related to {@link DnsServerAddressStreamProvider}. - */ -@UnstableApi -public final -class DnsServerAddressStreamProviders { - // TODO(scott): how is this done on Windows? This may require a JNI call to GetNetworkParams - // https://msdn.microsoft.com/en-us/library/aa365968(VS.85).aspx. - private static final DnsServerAddressStreamProvider DEFAULT_DNS_SERVER_ADDRESS_STREAM_PROVIDER = UnixResolverDnsServerAddressStreamProvider.parseSilently(); - - private - DnsServerAddressStreamProviders() { - } - - /** - * A {@link DnsServerAddressStreamProvider} which inherits the DNS servers from your local host's configuration. - *

- * Note that only macOS and Linux are currently supported. - * - * @return A {@link DnsServerAddressStreamProvider} which inherits the DNS servers from your local host's - * configuration. - */ - public static - DnsServerAddressStreamProvider platformDefault() { - return DEFAULT_DNS_SERVER_ADDRESS_STREAM_PROVIDER; - } -} diff --git a/src/dorkbox/network/dns/resolver/addressProvider/DnsServerAddresses.java b/src/dorkbox/network/dns/resolver/addressProvider/DnsServerAddresses.java deleted file mode 100644 index 2c69cedc..00000000 --- a/src/dorkbox/network/dns/resolver/addressProvider/DnsServerAddresses.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2014 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.addressProvider; - -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import dorkbox.network.dns.resolver.DnsNameResolver; -import io.netty.util.internal.UnstableApi; - -/** - * Provides an infinite sequence of DNS server addresses to {@link DnsNameResolver}. - */ -@UnstableApi -@SuppressWarnings("IteratorNextCanNotThrowNoSuchElementException") -public abstract -class DnsServerAddresses { - /** - * @deprecated Use {@link DefaultDnsServerAddressStreamProvider#defaultAddressList()}. - *

- * Returns the list of the system DNS server addresses. If it failed to retrieve the list of the system DNS server - * addresses from the environment, it will return {@code "8.8.8.8"} and {@code "8.8.4.4"}, the addresses of the - * Google public DNS servers. - */ - @Deprecated - public static - List defaultAddressList() { - return DefaultDnsServerAddressStreamProvider.defaultAddressList(); - } - - /** - * @deprecated Use {@link DefaultDnsServerAddressStreamProvider#defaultAddresses()}. - *

- * Returns the {@link DnsServerAddresses} that yields the system DNS server addresses sequentially. If it failed to - * retrieve the list of the system DNS server addresses from the environment, it will use {@code "8.8.8.8"} and - * {@code "8.8.4.4"}, the addresses of the Google public DNS servers. - *

- * This method has the same effect with the following code: - *

-     *         DnsServerAddresses.sequential(DnsServerAddresses.defaultAddressList());
-     *         
- *

- */ - @Deprecated - public static - DnsServerAddresses defaultAddresses() { - return DefaultDnsServerAddressStreamProvider.defaultAddresses(); - } - - /** - * Returns the {@link DnsServerAddresses} that yields the specified {@code addresses} sequentially. Once the - * last address is yielded, it will start again from the first address. - */ - public static - DnsServerAddresses sequential(Iterable addresses) { - return sequential0(sanitize(addresses)); - } - - private static - DnsServerAddresses sequential0(final InetSocketAddress... addresses) { - if (addresses.length == 1) { - return singleton(addresses[0]); - } - - return new DefaultDnsServerAddresses("sequential", addresses) { - @Override - public - DnsServerAddressStream stream() { - return new SequentialDnsServerAddressStream(addresses, 0); - } - }; - } - - /** - * Returns the {@link DnsServerAddresses} that yields only a single {@code address}. - */ - public static - DnsServerAddresses singleton(final InetSocketAddress address) { - if (address == null) { - throw new NullPointerException("address"); - } - if (address.isUnresolved()) { - throw new IllegalArgumentException("cannot use an unresolved DNS server address: " + address); - } - - return new SingletonDnsServerAddresses(address); - } - - private static - InetSocketAddress[] sanitize(Iterable addresses) { - if (addresses == null) { - throw new NullPointerException("addresses"); - } - - final List list; - if (addresses instanceof Collection) { - list = new ArrayList(((Collection) addresses).size()); - } - else { - list = new ArrayList(4); - } - - for (InetSocketAddress a : addresses) { - if (a == null) { - break; - } - if (a.isUnresolved()) { - throw new IllegalArgumentException("cannot use an unresolved DNS server address: " + a); - } - list.add(a); - } - - if (list.isEmpty()) { - throw new IllegalArgumentException("empty addresses"); - } - - return list.toArray(new InetSocketAddress[list.size()]); - } - - /** - * Returns the {@link DnsServerAddresses} that yields the specified {@code addresses} sequentially. Once the - * last address is yielded, it will start again from the first address. - */ - public static - DnsServerAddresses sequential(InetSocketAddress... addresses) { - return sequential0(sanitize(addresses)); - } - - private static - InetSocketAddress[] sanitize(InetSocketAddress[] addresses) { - if (addresses == null) { - throw new NullPointerException("addresses"); - } - - List list = new ArrayList(addresses.length); - for (InetSocketAddress a : addresses) { - if (a == null) { - break; - } - if (a.isUnresolved()) { - throw new IllegalArgumentException("cannot use an unresolved DNS server address: " + a); - } - list.add(a); - } - - if (list.isEmpty()) { - return DefaultDnsServerAddressStreamProvider.defaultAddressArray(); - } - - return list.toArray(new InetSocketAddress[list.size()]); - } - - /** - * Returns the {@link DnsServerAddresses} that yields the specified {@code address} in a shuffled order. Once all - * addresses are yielded, the addresses are shuffled again. - */ - public static - DnsServerAddresses shuffled(Iterable addresses) { - return shuffled0(sanitize(addresses)); - } - - private static - DnsServerAddresses shuffled0(final InetSocketAddress[] addresses) { - if (addresses.length == 1) { - return singleton(addresses[0]); - } - - return new DefaultDnsServerAddresses("shuffled", addresses) { - @Override - public - DnsServerAddressStream stream() { - return new ShuffledDnsServerAddressStream(addresses); - } - }; - } - - /** - * Returns the {@link DnsServerAddresses} that yields the specified {@code addresses} in a shuffled order. Once all - * addresses are yielded, the addresses are shuffled again. - */ - public static - DnsServerAddresses shuffled(InetSocketAddress... addresses) { - return shuffled0(sanitize(addresses)); - } - - /** - * Returns the {@link DnsServerAddresses} that yields the specified {@code addresses} in a rotational sequential - * order. It is similar to {@link #sequential(Iterable)}, but each {@link DnsServerAddressStream} starts from - * a different starting point. For example, the first {@link #stream()} will start from the first address, the - * second one will start from the second address, and so on. - */ - public static - DnsServerAddresses rotational(Iterable addresses) { - return rotational0(sanitize(addresses)); - } - - private static - DnsServerAddresses rotational0(final InetSocketAddress[] addresses) { - if (addresses.length == 1) { - return singleton(addresses[0]); - } - - return new RotationalDnsServerAddresses(addresses); - } - - /** - * Returns the {@link DnsServerAddresses} that yields the specified {@code addresses} in a rotational sequential - * order. It is similar to {@link #sequential(Iterable)}, but each {@link DnsServerAddressStream} starts from - * a different starting point. For example, the first {@link #stream()} will start from the first address, the - * second one will start from the second address, and so on. - */ - public static - DnsServerAddresses rotational(InetSocketAddress... addresses) { - return rotational0(sanitize(addresses)); - } - - /** - * Starts a new infinite stream of DNS server addresses. This method is invoked by {@link DnsNameResolver} on every - * uncached {@link DnsNameResolver#resolve(String)}or {@link DnsNameResolver#resolveAll(String)}. - */ - public abstract - DnsServerAddressStream stream(); -} diff --git a/src/dorkbox/network/dns/resolver/addressProvider/RotationalDnsServerAddresses.java b/src/dorkbox/network/dns/resolver/addressProvider/RotationalDnsServerAddresses.java deleted file mode 100644 index 67c905e2..00000000 --- a/src/dorkbox/network/dns/resolver/addressProvider/RotationalDnsServerAddresses.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2015 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.addressProvider; - -import java.net.InetSocketAddress; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; - -final -class RotationalDnsServerAddresses extends DefaultDnsServerAddresses { - - private static final AtomicIntegerFieldUpdater startIdxUpdater = AtomicIntegerFieldUpdater.newUpdater( - RotationalDnsServerAddresses.class, - "startIdx"); - - @SuppressWarnings("UnusedDeclaration") - private volatile int startIdx; - - RotationalDnsServerAddresses(InetSocketAddress[] addresses) { - super("rotational", addresses); - } - - @Override - public - DnsServerAddressStream stream() { - for (; ; ) { - int curStartIdx = startIdx; - int nextStartIdx = curStartIdx + 1; - if (nextStartIdx >= addresses.length) { - nextStartIdx = 0; - } - if (startIdxUpdater.compareAndSet(this, curStartIdx, nextStartIdx)) { - return new SequentialDnsServerAddressStream(addresses, curStartIdx); - } - } - } -} diff --git a/src/dorkbox/network/dns/resolver/addressProvider/SequentialDnsServerAddressStream.java b/src/dorkbox/network/dns/resolver/addressProvider/SequentialDnsServerAddressStream.java deleted file mode 100644 index 62f6cff3..00000000 --- a/src/dorkbox/network/dns/resolver/addressProvider/SequentialDnsServerAddressStream.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2015 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.addressProvider; - -import java.net.InetSocketAddress; - -final -class SequentialDnsServerAddressStream implements DnsServerAddressStream { - - private final InetSocketAddress[] addresses; - private int i; - - SequentialDnsServerAddressStream(InetSocketAddress[] addresses, int startIdx) { - this.addresses = addresses; - i = startIdx; - } - - @Override - public - InetSocketAddress next() { - int i = this.i; - InetSocketAddress next = addresses[i]; - if (++i < addresses.length) { - this.i = i; - } - else { - this.i = 0; - } - return next; - } - - @Override - public - int size() { - return addresses.length; - } - - @Override - public - SequentialDnsServerAddressStream duplicate() { - return new SequentialDnsServerAddressStream(addresses, i); - } - - @Override - public - String toString() { - return toString("sequential", i, addresses); - } - - static - String toString(String type, int index, InetSocketAddress[] addresses) { - final StringBuilder buf = new StringBuilder(type.length() + 2 + addresses.length * 16); - buf.append(type) - .append("(index: ") - .append(index); - buf.append(", addrs: ("); - for (InetSocketAddress a : addresses) { - buf.append(a) - .append(", "); - } - - buf.setLength(buf.length() - 2); - buf.append("))"); - - return buf.toString(); - } -} diff --git a/src/dorkbox/network/dns/resolver/addressProvider/SequentialDnsServerAddressStreamProvider.java b/src/dorkbox/network/dns/resolver/addressProvider/SequentialDnsServerAddressStreamProvider.java deleted file mode 100644 index 33abcd02..00000000 --- a/src/dorkbox/network/dns/resolver/addressProvider/SequentialDnsServerAddressStreamProvider.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.addressProvider; - -import java.net.InetSocketAddress; - -import io.netty.util.internal.UnstableApi; - -/** - * A {@link DnsServerAddressStreamProvider} which is backed by a sequential list of DNS servers. - */ -@UnstableApi -public final -class SequentialDnsServerAddressStreamProvider - extends UniSequentialDnsServerAddressStreamProvider { - /** - * Create a new instance. - * - * @param addresses The addresses which will be be returned in sequential order via - * {@link #nameServerAddressStream(String)} - */ - public - SequentialDnsServerAddressStreamProvider(InetSocketAddress... addresses) { - super(DnsServerAddresses.sequential(addresses)); - } - - /** - * Create a new instance. - * - * @param addresses The addresses which will be be returned in sequential order via - * {@link #nameServerAddressStream(String)} - */ - public - SequentialDnsServerAddressStreamProvider(Iterable addresses) { - super(DnsServerAddresses.sequential(addresses)); - } -} diff --git a/src/dorkbox/network/dns/resolver/addressProvider/ShuffledDnsServerAddressStream.java b/src/dorkbox/network/dns/resolver/addressProvider/ShuffledDnsServerAddressStream.java deleted file mode 100644 index 7298822a..00000000 --- a/src/dorkbox/network/dns/resolver/addressProvider/ShuffledDnsServerAddressStream.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2015 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.addressProvider; - -import java.net.InetSocketAddress; -import java.util.Random; - -import io.netty.util.internal.PlatformDependent; - -final -class ShuffledDnsServerAddressStream implements DnsServerAddressStream { - - private final InetSocketAddress[] addresses; - private int i; - - /** - * Create a new instance. - * - * @param addresses The addresses are not cloned. It is assumed the caller has cloned this array or otherwise will - * not modify the contents. - */ - ShuffledDnsServerAddressStream(InetSocketAddress[] addresses) { - this.addresses = addresses; - - shuffle(); - } - - private - void shuffle() { - final InetSocketAddress[] addresses = this.addresses; - final Random r = PlatformDependent.threadLocalRandom(); - - for (int i = addresses.length - 1; i >= 0; i--) { - InetSocketAddress tmp = addresses[i]; - int j = r.nextInt(i + 1); - addresses[i] = addresses[j]; - addresses[j] = tmp; - } - } - - private - ShuffledDnsServerAddressStream(InetSocketAddress[] addresses, int startIdx) { - this.addresses = addresses; - i = startIdx; - } - - @Override - public - InetSocketAddress next() { - int i = this.i; - InetSocketAddress next = addresses[i]; - if (++i < addresses.length) { - this.i = i; - } - else { - this.i = 0; - shuffle(); - } - return next; - } - - @Override - public - int size() { - return addresses.length; - } - - @Override - public - ShuffledDnsServerAddressStream duplicate() { - return new ShuffledDnsServerAddressStream(addresses, i); - } - - @Override - public - String toString() { - return SequentialDnsServerAddressStream.toString("shuffled", i, addresses); - } -} diff --git a/src/dorkbox/network/dns/resolver/addressProvider/SingletonDnsServerAddressStreamProvider.java b/src/dorkbox/network/dns/resolver/addressProvider/SingletonDnsServerAddressStreamProvider.java deleted file mode 100644 index a1de14d0..00000000 --- a/src/dorkbox/network/dns/resolver/addressProvider/SingletonDnsServerAddressStreamProvider.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.addressProvider; - -import java.net.InetSocketAddress; - -import io.netty.util.internal.UnstableApi; - -/** - * A {@link DnsServerAddressStreamProvider} which always uses a single DNS server for resolution. - */ -@UnstableApi -public final -class SingletonDnsServerAddressStreamProvider - extends UniSequentialDnsServerAddressStreamProvider { - /** - * Create a new instance. - * - * @param address The singleton address to use for every DNS resolution. - */ - public - SingletonDnsServerAddressStreamProvider(final InetSocketAddress address) { - super(DnsServerAddresses.singleton(address)); - } -} diff --git a/src/dorkbox/network/dns/resolver/addressProvider/SingletonDnsServerAddresses.java b/src/dorkbox/network/dns/resolver/addressProvider/SingletonDnsServerAddresses.java deleted file mode 100644 index 0fe2e49f..00000000 --- a/src/dorkbox/network/dns/resolver/addressProvider/SingletonDnsServerAddresses.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2015 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.addressProvider; - -import java.net.InetSocketAddress; - -final -class SingletonDnsServerAddresses extends DnsServerAddresses { - - private final InetSocketAddress address; - - private final DnsServerAddressStream stream = new DnsServerAddressStream() { - @Override - public - InetSocketAddress next() { - return address; - } - - @Override - public - int size() { - return 1; - } - - @Override - public - DnsServerAddressStream duplicate() { - return this; - } - - @Override - public - String toString() { - return SingletonDnsServerAddresses.this.toString(); - } - }; - - SingletonDnsServerAddresses(InetSocketAddress address) { - this.address = address; - } - - @Override - public - DnsServerAddressStream stream() { - return stream; - } - - @Override - public - String toString() { - return "singleton(" + address + ")"; - } -} diff --git a/src/dorkbox/network/dns/resolver/addressProvider/UniSequentialDnsServerAddressStreamProvider.java b/src/dorkbox/network/dns/resolver/addressProvider/UniSequentialDnsServerAddressStreamProvider.java deleted file mode 100644 index d5724d27..00000000 --- a/src/dorkbox/network/dns/resolver/addressProvider/UniSequentialDnsServerAddressStreamProvider.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.addressProvider; - -import io.netty.util.internal.ObjectUtil; - -/** - * A {@link DnsServerAddressStreamProvider} which is backed by a single {@link DnsServerAddresses}. - */ -abstract -class UniSequentialDnsServerAddressStreamProvider implements DnsServerAddressStreamProvider { - private final DnsServerAddresses addresses; - - UniSequentialDnsServerAddressStreamProvider(DnsServerAddresses addresses) { - this.addresses = ObjectUtil.checkNotNull(addresses, "addresses"); - } - - @Override - public final - DnsServerAddressStream nameServerAddressStream(String hostname) { - return addresses.stream(); - } -} diff --git a/src/dorkbox/network/dns/resolver/addressProvider/UnixResolverDnsServerAddressStreamProvider.java b/src/dorkbox/network/dns/resolver/addressProvider/UnixResolverDnsServerAddressStreamProvider.java deleted file mode 100644 index 700ee8cf..00000000 --- a/src/dorkbox/network/dns/resolver/addressProvider/UnixResolverDnsServerAddressStreamProvider.java +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright 2017 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.addressProvider; - -import static io.netty.util.internal.ObjectUtil.checkNotNull; -import static io.netty.util.internal.StringUtil.indexOfNonWhiteSpace; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import io.netty.util.NetUtil; -import io.netty.util.internal.SocketUtils; -import io.netty.util.internal.UnstableApi; -import io.netty.util.internal.logging.InternalLogger; -import io.netty.util.internal.logging.InternalLoggerFactory; - -/** - * Able to parse files such as /etc/resolv.conf and - * - * /etc/resolver to respect the system default domain servers. - */ -@UnstableApi -public final -class UnixResolverDnsServerAddressStreamProvider implements DnsServerAddressStreamProvider { - private static final InternalLogger logger = InternalLoggerFactory.getInstance(UnixResolverDnsServerAddressStreamProvider.class); - - private static final String ETC_RESOLV_CONF_FILE = "/etc/resolv.conf"; - private static final String ETC_RESOLVER_DIR = "/etc/resolver"; - private static final String NAMESERVER_ROW_LABEL = "nameserver"; - private static final String SORTLIST_ROW_LABEL = "sortlist"; - private static final String OPTIONS_ROW_LABEL = "options"; - private static final String DOMAIN_ROW_LABEL = "domain"; - private static final String PORT_ROW_LABEL = "port"; - - private static final String NDOTS_LABEL = "ndots:"; - - public static final int DEFAULT_NDOTS = 1; - - private final DnsServerAddresses defaultNameServerAddresses; - private final Map domainToNameServerStreamMap; - - /** - * Attempt to parse {@code /etc/resolv.conf} and files in the {@code /etc/resolver} directory by default. - * A failure to parse will return {@link DefaultDnsServerAddressStreamProvider}. - */ - static - DnsServerAddressStreamProvider parseSilently() { - try { - UnixResolverDnsServerAddressStreamProvider nameServerCache = new UnixResolverDnsServerAddressStreamProvider(ETC_RESOLV_CONF_FILE, - ETC_RESOLVER_DIR); - return nameServerCache.mayOverrideNameServers() ? nameServerCache : DefaultDnsServerAddressStreamProvider.INSTANCE; - } catch (Exception e) { - logger.debug("failed to parse {} and/or {}", ETC_RESOLV_CONF_FILE, ETC_RESOLVER_DIR, e); - return DefaultDnsServerAddressStreamProvider.INSTANCE; - } - } - - private - boolean mayOverrideNameServers() { - return !domainToNameServerStreamMap.isEmpty() || defaultNameServerAddresses.stream() - .next() != null; - } - - /** - * Parse a file of the format /etc/resolv.conf which may contain - * the default DNS server to use, and also overrides for individual domains. Also parse a directory of the format - * - * /etc/resolver which may contain multiple files to override the name servers used for multimple domains. - * - * @param etcResolvConf /etc/resolv.conf. - * @param etcResolverDir Directory containing files of the format defined in - * - * /etc/resolver. - * - * @throws IOException If an error occurs while parsing the input files. - */ - public - UnixResolverDnsServerAddressStreamProvider(String etcResolvConf, String etcResolverDir) throws IOException { - this(etcResolvConf == null ? null : new File(etcResolvConf), etcResolverDir == null ? null : new File(etcResolverDir).listFiles()); - } - - /** - * Parse a file of the format /etc/resolv.conf which may contain - * the default DNS server to use, and also overrides for individual domains. Also parse list of files of the format - * - * /etc/resolver which may contain multiple files to override the name servers used for multimple domains. - * - * @param etcResolvConf /etc/resolv.conf. - * @param etcResolverFiles List of files of the format defined in - * - * /etc/resolver. - * - * @throws IOException If an error occurs while parsing the input files. - */ - public - UnixResolverDnsServerAddressStreamProvider(File etcResolvConf, File... etcResolverFiles) throws IOException { - Map etcResolvConfMap = parse(checkNotNull(etcResolvConf, "etcResolvConf")); - final boolean useEtcResolverFiles = etcResolverFiles != null && etcResolverFiles.length != 0; - domainToNameServerStreamMap = useEtcResolverFiles ? parse(etcResolverFiles) : etcResolvConfMap; - - DnsServerAddresses defaultNameServerAddresses = etcResolvConfMap.get(etcResolvConf.getName()); - if (defaultNameServerAddresses == null) { - Collection values = etcResolvConfMap.values(); - if (values.isEmpty()) { - throw new IllegalArgumentException(etcResolvConf + " didn't provide any name servers"); - } - this.defaultNameServerAddresses = values.iterator() - .next(); - } - else { - this.defaultNameServerAddresses = defaultNameServerAddresses; - } - - if (useEtcResolverFiles) { - domainToNameServerStreamMap.putAll(etcResolvConfMap); - } - } - - private static - Map parse(File... etcResolverFiles) throws IOException { - Map domainToNameServerStreamMap = new HashMap(etcResolverFiles.length << 1); - for (File etcResolverFile : etcResolverFiles) { - if (!etcResolverFile.isFile()) { - continue; - } - FileReader fr = new FileReader(etcResolverFile); - BufferedReader br = null; - try { - br = new BufferedReader(fr); - List addresses = new ArrayList(2); - String domainName = etcResolverFile.getName(); - int port = DefaultDnsServerAddressStreamProvider.DNS_PORT; - String line; - while ((line = br.readLine()) != null) { - line = line.trim(); - char c; - if (line.isEmpty() || (c = line.charAt(0)) == '#' || c == ';') { - continue; - } - if (line.startsWith(NAMESERVER_ROW_LABEL)) { - int i = indexOfNonWhiteSpace(line, NAMESERVER_ROW_LABEL.length()); - if (i < 0) { - throw new IllegalArgumentException("error parsing label " + NAMESERVER_ROW_LABEL + " in file " + - etcResolverFile + ". value: " + line); - } - String maybeIP = line.substring(i); - // There may be a port appended onto the IP address so we attempt to extract it. - if (!NetUtil.isValidIpV4Address(maybeIP) && !NetUtil.isValidIpV6Address(maybeIP)) { - i = maybeIP.lastIndexOf('.'); - if (i + 1 >= maybeIP.length()) { - throw new IllegalArgumentException("error parsing label " + NAMESERVER_ROW_LABEL + " in file " + - etcResolverFile + ". invalid IP value: " + line); - } - port = Integer.parseInt(maybeIP.substring(i + 1)); - maybeIP = maybeIP.substring(0, i); - } - addresses.add(SocketUtils.socketAddress(maybeIP, port)); - } - else if (line.startsWith(DOMAIN_ROW_LABEL)) { - int i = indexOfNonWhiteSpace(line, DOMAIN_ROW_LABEL.length()); - if (i < 0) { - throw new IllegalArgumentException("error parsing label " + DOMAIN_ROW_LABEL + " in file " + etcResolverFile + - " value: " + line); - } - domainName = line.substring(i); - if (!addresses.isEmpty()) { - putIfAbsent(domainToNameServerStreamMap, domainName, addresses); - } - addresses = new ArrayList(2); - } - else if (line.startsWith(PORT_ROW_LABEL)) { - int i = indexOfNonWhiteSpace(line, PORT_ROW_LABEL.length()); - if (i < 0) { - throw new IllegalArgumentException("error parsing label " + PORT_ROW_LABEL + " in file " + etcResolverFile + - " value: " + line); - } - port = Integer.parseInt(line.substring(i)); - } - else if (line.startsWith(SORTLIST_ROW_LABEL)) { - logger.info("row type {} not supported. ignoring line: {}", SORTLIST_ROW_LABEL, line); - } - } - if (!addresses.isEmpty()) { - putIfAbsent(domainToNameServerStreamMap, domainName, addresses); - } - } finally { - if (br == null) { - fr.close(); - } - else { - br.close(); - } - } - } - return domainToNameServerStreamMap; - } - - private static - void putIfAbsent(Map domainToNameServerStreamMap, String domainName, List addresses) { - // TODO(scott): sortlist is being ignored. - putIfAbsent(domainToNameServerStreamMap, domainName, DnsServerAddresses.sequential(addresses)); - } - - private static - void putIfAbsent(Map domainToNameServerStreamMap, String domainName, DnsServerAddresses addresses) { - DnsServerAddresses existingAddresses = domainToNameServerStreamMap.put(domainName, addresses); - if (existingAddresses != null) { - domainToNameServerStreamMap.put(domainName, existingAddresses); - logger.debug("Domain name {} already maps to addresses {} so new addresses {} will be discarded", - domainName, - existingAddresses, - addresses); - } - } - - @Override - public - DnsServerAddressStream nameServerAddressStream(String hostname) { - for (; ; ) { - int i = hostname.indexOf('.', 1); - if (i < 0 || i == hostname.length() - 1) { - return defaultNameServerAddresses.stream(); - } - - DnsServerAddresses addresses = domainToNameServerStreamMap.get(hostname); - if (addresses != null) { - return addresses.stream(); - } - - hostname = hostname.substring(i + 1); - } - } - - /** - * Parse a file of the format /etc/resolv.conf and return the - * value corresponding to the first ndots in an options configuration. - * - * @return the value corresponding to the first ndots in an options configuration, or {@link #DEFAULT_NDOTS} if not - * found. - * - * @throws IOException If a failure occurs parsing the file. - */ - public static - int parseEtcResolverFirstNdots() throws IOException { - return parseEtcResolverFirstNdots(new File(ETC_RESOLV_CONF_FILE)); - } - - /** - * Parse a file of the format /etc/resolv.conf and return the - * value corresponding to the first ndots in an options configuration. - * - * @param etcResolvConf a file of the format /etc/resolv.conf. - * - * @return the value corresponding to the first ndots in an options configuration, or {@link #DEFAULT_NDOTS} if not - * found. - * - * @throws IOException If a failure occurs parsing the file. - */ - static - int parseEtcResolverFirstNdots(File etcResolvConf) throws IOException { - FileReader fr = new FileReader(etcResolvConf); - BufferedReader br = null; - try { - br = new BufferedReader(fr); - String line; - while ((line = br.readLine()) != null) { - if (line.startsWith(OPTIONS_ROW_LABEL)) { - int i = line.indexOf(NDOTS_LABEL); - if (i >= 0) { - i += NDOTS_LABEL.length(); - final int j = line.indexOf(' ', i); - return Integer.parseInt(line.substring(i, j < 0 ? line.length() : j)); - } - break; - } - } - } finally { - if (br == null) { - fr.close(); - } - else { - br.close(); - } - } - return DEFAULT_NDOTS; - } -} diff --git a/src/dorkbox/network/dns/resolver/cache/DefaultDnsCache.java b/src/dorkbox/network/dns/resolver/cache/DefaultDnsCache.java deleted file mode 100644 index 51f7062e..00000000 --- a/src/dorkbox/network/dns/resolver/cache/DefaultDnsCache.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2016 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.cache; - -import static io.netty.util.internal.ObjectUtil.checkNotNull; -import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero; - -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.TimeUnit; - -import dorkbox.network.dns.records.DnsRecord; -import io.netty.channel.EventLoop; -import io.netty.util.internal.PlatformDependent; -import io.netty.util.internal.UnstableApi; - -/** - * Default implementation of {@link DnsCache}, backed by a {@link ConcurrentMap}. - * If any additional {@link DnsRecord} is used, no caching takes place. - */ -@UnstableApi -public class DefaultDnsCache implements DnsCache { - - private final ConcurrentMap> resolveCache = PlatformDependent.newConcurrentHashMap(); - private final int minTtl; - private final int maxTtl; - private final int negativeTtl; - - /** - * Create a cache that respects the TTL returned by the DNS server - * and doesn't cache negative responses. - */ - public DefaultDnsCache() { - this(0, Integer.MAX_VALUE, 0); - } - - /** - * Create a cache. - * @param minTtl the minimum TTL - * @param maxTtl the maximum TTL - * @param negativeTtl the TTL for failed queries - */ - public DefaultDnsCache(int minTtl, int maxTtl, int negativeTtl) { - this.minTtl = checkPositiveOrZero(minTtl, "minTtl"); - this.maxTtl = checkPositiveOrZero(maxTtl, "maxTtl"); - if (minTtl > maxTtl) { - throw new IllegalArgumentException( - "minTtl: " + minTtl + ", maxTtl: " + maxTtl + " (expected: 0 <= minTtl <= maxTtl)"); - } - this.negativeTtl = checkPositiveOrZero(negativeTtl, "negativeTtl"); - } - - /** - * Returns the minimum TTL of the cached DNS resource records (in seconds). - * - * @see #maxTtl() - */ - public int minTtl() { - return minTtl; - } - - /** - * Returns the maximum TTL of the cached DNS resource records (in seconds). - * - * @see #minTtl() - */ - public int maxTtl() { - return maxTtl; - } - - /** - * Returns the TTL of the cache for the failed DNS queries (in seconds). The default value is {@code 0}, which - * disables the cache for negative results. - */ - public int negativeTtl() { - return negativeTtl; - } - - @Override - public void clear() { - for (Iterator>> i = resolveCache.entrySet().iterator(); i.hasNext();) { - final Map.Entry> e = i.next(); - i.remove(); - cancelExpiration(e.getValue()); - } - } - - @Override - public boolean clear(String hostname) { - checkNotNull(hostname, "hostname"); - boolean removed = false; - for (Iterator>> i = resolveCache.entrySet().iterator(); i.hasNext();) { - final Map.Entry> e = i.next(); - if (e.getKey().equals(hostname)) { - i.remove(); - cancelExpiration(e.getValue()); - removed = true; - } - } - return removed; - } - - @Override - public List get(String hostname) { - checkNotNull(hostname, "hostname"); - return resolveCache.get(hostname); - } - - private List cachedEntries(String hostname) { - List oldEntries = resolveCache.get(hostname); - final List entries; - if (oldEntries == null) { - List newEntries = new ArrayList(8); - oldEntries = resolveCache.putIfAbsent(hostname, newEntries); - entries = oldEntries != null? oldEntries : newEntries; - } else { - entries = oldEntries; - } - return entries; - } - - @Override - public void cache(String hostname, InetAddress address, long originalTtl, EventLoop loop) { - checkNotNull(hostname, "hostname"); - checkNotNull(address, "address"); - checkNotNull(loop, "loop"); - if (maxTtl == 0) { - return; - } - final int ttl = Math.max(minTtl, (int) Math.min(maxTtl, originalTtl)); - final List entries = cachedEntries(hostname); - final DnsCacheEntry e = new DnsCacheEntry(hostname, address); - - synchronized (entries) { - if (!entries.isEmpty()) { - final DnsCacheEntry firstEntry = entries.get(0); - if (firstEntry.cause() != null) { - assert entries.size() == 1; - firstEntry.cancelExpiration(); - entries.clear(); - } - } - entries.add(e); - } - - scheduleCacheExpiration(entries, e, ttl, loop); - } - - @Override - public void cache(String hostname, Throwable cause, EventLoop loop) { - checkNotNull(hostname, "hostname"); - checkNotNull(cause, "cause"); - checkNotNull(loop, "loop"); - - if (negativeTtl == 0) { - return; - } - final List entries = cachedEntries(hostname); - final DnsCacheEntry e = new DnsCacheEntry(hostname, cause); - - synchronized (entries) { - final int numEntries = entries.size(); - for (int i = 0; i < numEntries; i ++) { - entries.get(i).cancelExpiration(); - } - entries.clear(); - entries.add(e); - } - - scheduleCacheExpiration(entries, e, negativeTtl, loop); - } - - private static void cancelExpiration(List entries) { - final int numEntries = entries.size(); - for (int i = 0; i < numEntries; i++) { - entries.get(i).cancelExpiration(); - } - } - - private void scheduleCacheExpiration(final List entries, - final DnsCacheEntry e, - int ttl, - EventLoop loop) { - e.scheduleExpiration(loop, new Runnable() { - @Override - public void run() { - synchronized (entries) { - entries.remove(e); - if (entries.isEmpty()) { - resolveCache.remove(e.hostname()); - } - } - } - }, ttl, TimeUnit.SECONDS); - } - - @Override - public String toString() { - return new StringBuilder() - .append("DefaultDnsCache(minTtl=") - .append(minTtl).append(", maxTtl=") - .append(maxTtl).append(", negativeTtl=") - .append(negativeTtl).append(", cached resolved hostname=") - .append(resolveCache.size()).append(")") - .toString(); - } -} diff --git a/src/dorkbox/network/dns/resolver/cache/DnsCache.java b/src/dorkbox/network/dns/resolver/cache/DnsCache.java deleted file mode 100644 index 839a04a9..00000000 --- a/src/dorkbox/network/dns/resolver/cache/DnsCache.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2016 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.cache; - -import java.net.InetAddress; -import java.util.List; - -import io.netty.channel.EventLoop; -import io.netty.util.internal.UnstableApi; - -/** - * A cache for DNS resolution entries. - */ -@UnstableApi -public interface DnsCache { - - /** - * Clears all the resolved addresses cached by this resolver. - * - * @see #clear(String) - */ - void clear(); - - /** - * Clears the resolved addresses of the specified host name from the cache of this resolver. - * - * @return {@code true} if and only if there was an entry for the specified host name in the cache and - * it has been removed by this method - */ - boolean clear(String hostname); - - /** - * Return the cached entries for the given hostname. - * @param hostname the hostname - * @return the cached entries - */ - List get(String hostname); - - /** - * Cache a resolved address for a given hostname. - * @param hostname the hostname - * @param address the resolved address - * @param originalTtl the TLL as returned by the DNS server - * @param loop the {@link EventLoop} used to register the TTL timeout - */ - void cache(String hostname, InetAddress address, long originalTtl, EventLoop loop); - - /** - * Cache the resolution failure for a given hostname. - * @param hostname the hostname - * @param cause the resolution failure - * @param loop the {@link EventLoop} used to register the TTL timeout - */ - void cache(String hostname, Throwable cause, EventLoop loop); -} diff --git a/src/dorkbox/network/dns/resolver/cache/DnsCacheEntry.java b/src/dorkbox/network/dns/resolver/cache/DnsCacheEntry.java deleted file mode 100644 index a3694d4c..00000000 --- a/src/dorkbox/network/dns/resolver/cache/DnsCacheEntry.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2015 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.cache; - -import static io.netty.util.internal.ObjectUtil.checkNotNull; - -import java.net.InetAddress; -import java.util.concurrent.TimeUnit; - -import io.netty.channel.EventLoop; -import io.netty.util.concurrent.ScheduledFuture; -import io.netty.util.internal.UnstableApi; - -/** - * Entry in {@link DnsCache}. - */ -@UnstableApi -public final class DnsCacheEntry { - - private final String hostname; - private final InetAddress address; - private final Throwable cause; - private volatile ScheduledFuture expirationFuture; - - public DnsCacheEntry(String hostname, InetAddress address) { - this.hostname = checkNotNull(hostname, "hostname"); - this.address = checkNotNull(address, "address"); - cause = null; - } - - public DnsCacheEntry(String hostname, Throwable cause) { - this.hostname = checkNotNull(hostname, "hostname"); - this.cause = checkNotNull(cause, "cause"); - address = null; - } - - public String hostname() { - return hostname; - } - - public InetAddress address() { - return address; - } - - public Throwable cause() { - return cause; - } - - void scheduleExpiration(EventLoop loop, Runnable task, long delay, TimeUnit unit) { - assert expirationFuture == null: "expiration task scheduled already"; - expirationFuture = loop.schedule(task, delay, unit); - } - - void cancelExpiration() { - ScheduledFuture expirationFuture = this.expirationFuture; - if (expirationFuture != null) { - expirationFuture.cancel(false); - } - } - - @Override - public String toString() { - if (cause != null) { - return hostname + '/' + cause; - } else { - return address.toString(); - } - } -} diff --git a/src/dorkbox/network/dns/resolver/cache/NoopDnsCache.java b/src/dorkbox/network/dns/resolver/cache/NoopDnsCache.java deleted file mode 100644 index 7e5a11a2..00000000 --- a/src/dorkbox/network/dns/resolver/cache/NoopDnsCache.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2016 The Netty Project - * - * The Netty Project licenses this file to you 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 dorkbox.network.dns.resolver.cache; - -import java.net.InetAddress; -import java.util.Collections; -import java.util.List; - -import io.netty.channel.EventLoop; -import io.netty.util.internal.UnstableApi; - -/** - * A noop DNS cache that actually never caches anything. - */ -@UnstableApi -public final class NoopDnsCache implements DnsCache { - - public static final NoopDnsCache INSTANCE = new NoopDnsCache(); - - /** - * Private singleton constructor. - */ - private NoopDnsCache() { - } - - @Override - public void clear() { - } - - @Override - public boolean clear(String hostname) { - return false; - } - - @Override - public List get(String hostname) { - return Collections.emptyList(); - } - - @Override - public void cache(String hostname, InetAddress address, long originalTtl, EventLoop loop) { - } - - @Override - public void cache(String hostname, Throwable cause, EventLoop loop) { - } - - @Override - public String toString() { - return NoopDnsCache.class.getSimpleName(); - } -} diff --git a/src/dorkbox/network/dns/server/CNAMEResponse.java b/src/dorkbox/network/dns/server/CNAMEResponse.java deleted file mode 100644 index 0dd044c6..00000000 --- a/src/dorkbox/network/dns/server/CNAMEResponse.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.server; - - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.records.DnsMessage; -import dorkbox.network.dns.records.DnsRecord; - -public class CNAMEResponse extends DefaultResponse { - final Name cname; - final int qtype; - - public CNAMEResponse(DnsRecord cname, int queryType) { - super(DnsResponseCode.NOERROR); - this.cname = cname.getName(); - this.qtype = queryType; - } - - @Override - public void postProcess(DnsMessage message) { - System.err.println("WHAT?"); - - // context.response().answer().add(this.cname); - // Response r = context.resolve(this.cname.oneName(), this.qtype); - // r.postProcess(context); - } -} diff --git a/src/dorkbox/network/dns/server/DNAMEResponse.java b/src/dorkbox/network/dns/server/DNAMEResponse.java deleted file mode 100644 index a9c59ad1..00000000 --- a/src/dorkbox/network/dns/server/DNAMEResponse.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.server; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.records.DnsMessage; -import dorkbox.network.dns.records.DnsRecord; - -public class DNAMEResponse extends DefaultResponse { - - final Name dname; - final Name qname; - final int qtype; - - public DNAMEResponse(DnsRecord dname, Name qname, int qtype) { - super(DnsResponseCode.NOERROR); - - this.dname = dname.getName(); - this.qname = qname; - this.qtype = qtype; - } - - @Override - public void postProcess(DnsMessage context) { - System.err.println("WWHAT?"); - // DNSMessage res = context.response(); - // res.answer().add(this.dname); - // Name name = this.qname.replace(this.dname.name(), this.dname.oneName()); - // if (name == null) { - // context.response().header().rcode(RCode.YXDomain); - // } else { - // SingleNameRecord cname = new SingleNameRecord(RRType.CNAME, name); - // cname.name(this.qname); - // res.answer().add(cname); - // res.header().aa(true); - // Response r = context.resolve(name, this.qtype); - // r.postProcess(context); - // } - } -} diff --git a/src/dorkbox/network/dns/server/DefaultResponse.java b/src/dorkbox/network/dns/server/DefaultResponse.java deleted file mode 100644 index d2baa942..00000000 --- a/src/dorkbox/network/dns/server/DefaultResponse.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.server; - -/** - * - */ -public abstract -class DefaultResponse implements Response { - private final int responseCode; - - public - DefaultResponse(int responseCode) { - this.responseCode = responseCode; - } - - @Override - public - int responseCode() { - return responseCode; - } -} diff --git a/src/dorkbox/network/dns/server/NoErrorResponse.java b/src/dorkbox/network/dns/server/NoErrorResponse.java deleted file mode 100644 index 9360f02d..00000000 --- a/src/dorkbox/network/dns/server/NoErrorResponse.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.server; - -import java.util.Set; - -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.constants.Flags; -import dorkbox.network.dns.records.DnsMessage; -import dorkbox.network.dns.records.DnsRecord; - -public -class NoErrorResponse extends DefaultResponse { - final Set records; - final boolean authoritativeAnswer; - - public - NoErrorResponse(Set records) { - this(records, true); - } - - public - NoErrorResponse(Set records, boolean authoritativeAnswer) { - super(DnsResponseCode.NOERROR); - this.records = records; - this.authoritativeAnswer = authoritativeAnswer; - } - - @Override - public - void postProcess(DnsMessage message) { - message.getHeader() - .setRcode(this.responseCode()); - - message.getHeader() - .setFlag(Flags.QR); - - if (this.authoritativeAnswer) { - message.getHeader() - .setFlag(Flags.AA); - } - else { - message.getHeader() - .unsetFlag(Flags.AA); - } - - for (DnsRecord record : records) { - message.addRecord(record, DnsSection.ANSWER); - } - - // TODO additional section ? - } -} diff --git a/src/dorkbox/network/dns/server/NotFoundResponse.java b/src/dorkbox/network/dns/server/NotFoundResponse.java deleted file mode 100644 index a625e265..00000000 --- a/src/dorkbox/network/dns/server/NotFoundResponse.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.server; - -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.records.DnsMessage; -import dorkbox.network.dns.records.SOARecord; - -/** - * - */ -public -class NotFoundResponse extends DefaultResponse { - - final SOARecord soaRecord; - - public - NotFoundResponse(int rcode, SOARecord soaRecord) { - super(rcode); - this.soaRecord = soaRecord; - } - - @Override - public - void postProcess(DnsMessage message) { - message.getHeader().setRcode(this.responseCode()); - message.addRecord(this.soaRecord, DnsSection.AUTHORITY); - } -} diff --git a/src/dorkbox/network/dns/server/ReferralResponse.java b/src/dorkbox/network/dns/server/ReferralResponse.java deleted file mode 100644 index 0447df78..00000000 --- a/src/dorkbox/network/dns/server/ReferralResponse.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.server; - -import java.util.Set; - -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.records.DnsMessage; -import dorkbox.network.dns.records.DnsRecord; - -public class ReferralResponse extends DefaultResponse { - final Set nsRecords; - - public ReferralResponse(Set records) { - super(DnsResponseCode.NOERROR); - this.nsRecords = records; - } - - @Override - public void postProcess(DnsMessage message) { - message.getHeader().setRcode(this.responseCode()); - - for (DnsRecord nsRecord : nsRecords) { - message.addRecord(nsRecord, DnsSection.AUTHORITY); - } - } -} diff --git a/src/dorkbox/network/dns/server/Response.java b/src/dorkbox/network/dns/server/Response.java deleted file mode 100644 index 5607711b..00000000 --- a/src/dorkbox/network/dns/server/Response.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.server; - -import dorkbox.network.dns.records.DnsMessage; - -/** - * - */ -public -interface Response { - int responseCode(); - - void postProcess(DnsMessage message); -} diff --git a/src/dorkbox/network/dns/serverHandlers/DnsDecisionHandler.java b/src/dorkbox/network/dns/serverHandlers/DnsDecisionHandler.java deleted file mode 100644 index 01646f1c..00000000 --- a/src/dorkbox/network/dns/serverHandlers/DnsDecisionHandler.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.serverHandlers; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.List; - -import org.slf4j.Logger; - -import dorkbox.network.DnsClient; -import dorkbox.network.dns.DnsEnvelope; -import dorkbox.network.dns.DnsServerResponse; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsOpCode; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.constants.Flags; -import dorkbox.network.dns.records.ARecord; -import dorkbox.network.dns.records.DnsMessage; -import dorkbox.network.dns.records.DnsRecord; -import dorkbox.network.dns.records.Header; -import dorkbox.network.dns.records.Update; -import dorkbox.network.dns.resolver.DnsNameResolver; -import dorkbox.util.collections.LockFreeHashMap; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; - -public -class DnsDecisionHandler extends ChannelInboundHandlerAdapter { - - private final Logger logger; - private final LockFreeHashMap> aRecordMap; - private final DnsClient dnsClient; - - public - DnsDecisionHandler(final Logger logger) { - this.logger = logger; - - dnsClient = new DnsClient(); - dnsClient.start(); - - aRecordMap = new LockFreeHashMap>(); - } - - /** - * Adds a domain name query result, so clients that request the domain name will get the ipAddress - * - * @param domainName the domain name to have results for - * @param aRecords the A records (can be multiple) to return for the requested domain name - */ - public - void addARecord(final Name domainName, final ArrayList aRecords) { - aRecordMap.put(domainName, aRecords); - } - - @Override - public - void channelRead(ChannelHandlerContext context, Object message) throws Exception { - onChannelRead(context, (DnsEnvelope) message); - } - - @Override - public - void exceptionCaught(final ChannelHandlerContext context, final Throwable cause) throws Exception { - logger.error("DecisionHandler#exceptionCaught", cause); - super.exceptionCaught(context, cause); - } - - private - void onChannelRead(final ChannelHandlerContext context, final DnsEnvelope dnsMessage) { - int opcode = dnsMessage.getHeader() - .getOpcode(); - - switch (opcode) { - case DnsOpCode.QUERY: - onQuery(context, dnsMessage, dnsMessage.recipient()); - return; - - case DnsOpCode.IQUERY: - onIQuery(context, dnsMessage, dnsMessage.recipient()); - return; - - case DnsOpCode.NOTIFY: - onNotify(context, dnsMessage, dnsMessage.recipient()); - return; - - case DnsOpCode.STATUS: - onStatus(context, dnsMessage, dnsMessage.recipient()); - return; - - case DnsOpCode.UPDATE: - onUpdate(context, (Update) (DnsMessage) dnsMessage, dnsMessage.recipient()); - return; - - default: - logger.error("Unknown DNS opcode {} from {}", - opcode, - context.channel() - .remoteAddress()); - } - } - - private - void onIQuery(final ChannelHandlerContext context, final DnsMessage dnsQuestion, final InetSocketAddress recipient) { - System.err.println("DECISION HANDLER READ"); - System.err.println(dnsQuestion); - } - - private - void onNotify(final ChannelHandlerContext context, final DnsMessage dnsQuestion, final InetSocketAddress recipient) { - System.err.println("DECISION HANDLER READ"); - System.err.println(dnsQuestion); - } - - private - void onQuery(final ChannelHandlerContext context, final DnsMessage dnsQuestion, final InetSocketAddress recipient) { - // either I have an answer, or I don't (and have to forward to another DNS server - // it might be more than 1 question... - Header header = dnsQuestion.getHeader(); - int count = header.getCount(DnsSection.QUESTION); - - // we don't support more than 1 question at a time. - if (count == 1) { - DnsRecord[] sectionArray = dnsQuestion.getSectionArray(DnsSection.QUESTION); - final DnsRecord dnsRecord = sectionArray[0]; - final Name name = dnsRecord.getName(); - final long ttl = dnsRecord.getTTL(); - final int type = dnsRecord.getType(); - - - // what type of record? A, AAAA, MX, PTR, etc? - if (DnsRecordType.A == type) { - DnsNameResolver resolver = dnsClient.getResolver(); - - String domainName = name.toString(true); - - // check to see if we have it in our local hosts file - final InetAddress inetAddress = resolver.resolveHostsFileEntry(domainName); - if (inetAddress != null) { - DnsServerResponse dnsResponse = new DnsServerResponse(dnsQuestion, - (InetSocketAddress) context.channel() - .localAddress(), - recipient); - - Header responseHeader = dnsResponse.getHeader(); - responseHeader.setFlag(Flags.QR); - responseHeader.setRcode(DnsResponseCode.NOERROR); - - dnsResponse.addRecord(dnsRecord, DnsSection.QUESTION); - - ARecord aRecord = new ARecord(name, dnsRecord.getDClass(), ttl, inetAddress); - dnsResponse.addRecord(aRecord, DnsSection.ANSWER); - - context.channel() - .write(dnsResponse); - - return; - } - - - // check our local cache - ArrayList records = aRecordMap.get(name); - if (records != null) { - DnsServerResponse dnsResponse = new DnsServerResponse(dnsQuestion, - (InetSocketAddress) context.channel() - .localAddress(), - recipient); - - Header responseHeader = dnsResponse.getHeader(); - responseHeader.setFlag(Flags.QR); - responseHeader.setRcode(DnsResponseCode.NOERROR); - - dnsResponse.addRecord(dnsRecord, DnsSection.QUESTION); - - for (ARecord record : records) { - dnsResponse.addRecord(record, DnsSection.ANSWER); - logger.debug("Writing A record response: {}", record.getAddress()); - } - - context.channel() - .write(dnsResponse); - - return; - } - else { - // have to send this on to the forwarder - logger.debug("Sending DNS query to the forwarder..."); - - - // use "resolve", since it handles A/AAAA records + redirects correctly - resolver.resolveAll(domainName) - .addListener(new FutureListener>() { - @Override - public - void operationComplete(final Future> future) throws Exception { - List resolvedAddresses = future.getNow(); - - DnsServerResponse dnsResponse = new DnsServerResponse(dnsQuestion, - (InetSocketAddress) context.channel() - .localAddress(), - recipient); - - Header responseHeader = dnsResponse.getHeader(); - responseHeader.setFlag(Flags.QR); - - dnsResponse.addRecord(dnsRecord, DnsSection.QUESTION); - - if (resolvedAddresses == null || resolvedAddresses.isEmpty()) { - responseHeader.setRcode(DnsResponseCode.NXDOMAIN); - } - else { - responseHeader.setRcode(DnsResponseCode.NOERROR); - - ArrayList records = new ArrayList(); - - for (int i = 0; i < resolvedAddresses.size(); i++) { - final InetAddress resolvedAddress = resolvedAddresses.get(i); - - ARecord record = new ARecord(name, dnsRecord.getDClass(), ttl, resolvedAddress); - records.add(record); - dnsResponse.addRecord(record, DnsSection.ANSWER); - } - - - // we got here because there were no cached records in our record map -- so we save them! - // duplicates are not an issue because they will always be the same answer - aRecordMap.put(name, records); - } - - context.channel() - .write(dnsResponse); - - } - }); - } - } - return; - } - - DnsRecord[] sectionArray = dnsQuestion.getSectionArray(DnsSection.QUESTION); - DnsRecord dnsRecord = sectionArray[0]; - - System.err.println(dnsRecord); - } - - private - void onStatus(final ChannelHandlerContext context, final DnsMessage dnsQuestion, final InetSocketAddress recipient) { - System.err.println("DECISION HANDLER READ"); - System.err.println(dnsQuestion); - } - - private - void onUpdate(final ChannelHandlerContext context, final Update dnsUpdate, final InetSocketAddress recipient) { - System.err.println("DECISION HANDLER READ"); - System.err.println(dnsUpdate); - } - - public - void stop() { - dnsClient.stop(); - } -} diff --git a/src/dorkbox/network/dns/serverHandlers/DnsMessageDecoder.java b/src/dorkbox/network/dns/serverHandlers/DnsMessageDecoder.java deleted file mode 100644 index b82179da..00000000 --- a/src/dorkbox/network/dns/serverHandlers/DnsMessageDecoder.java +++ /dev/null @@ -1,54 +0,0 @@ -package dorkbox.network.dns.serverHandlers; - -import java.net.InetSocketAddress; -import java.util.List; - -import org.slf4j.Logger; - -import dorkbox.network.dns.DnsEnvelope; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.network.dns.records.Header; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.socket.DatagramPacket; -import io.netty.handler.codec.MessageToMessageDecoder; - -class DnsMessageDecoder extends MessageToMessageDecoder { - private final Logger logger; - - DnsMessageDecoder(final Logger logger) { - this.logger = logger; - } - - @Override - public - void exceptionCaught(final ChannelHandlerContext context, final Throwable cause) throws Exception { - logger.error("DnsMessageDecoder#exceptionCaught", cause); - super.exceptionCaught(context, cause); - } - - @Override - protected - void decode(ChannelHandlerContext context, DatagramPacket packet, List out) throws Exception { - final ByteBuf buf = packet.content(); - - // Check that the response is long enough. - if (buf.readableBytes() < Header.LENGTH) { - throw new WireParseException("invalid DNS header - " + "too short"); - } - - boolean success = false; - try { - InetSocketAddress localAddress = packet.recipient(); - InetSocketAddress remoteAddress = packet.sender(); - - DnsEnvelope dnsEnvelope = new DnsEnvelope(buf, localAddress, remoteAddress); - out.add(dnsEnvelope); - success = true; - } finally { - if (!success) { - buf.release(); - } - } - } -} diff --git a/src/dorkbox/network/dns/serverHandlers/DnsMessageEncoder.java b/src/dorkbox/network/dns/serverHandlers/DnsMessageEncoder.java deleted file mode 100644 index 63e82ed2..00000000 --- a/src/dorkbox/network/dns/serverHandlers/DnsMessageEncoder.java +++ /dev/null @@ -1,81 +0,0 @@ -package dorkbox.network.dns.serverHandlers; - -import java.io.IOException; - -import org.slf4j.Logger; - -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.DnsServerResponse; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.socket.DatagramPacket; -import io.netty.handler.codec.MessageToByteEncoder; - -/** - * - */ -@ChannelHandler.Sharable -public -class DnsMessageEncoder extends MessageToByteEncoder { - private final Logger logger; - - public - DnsMessageEncoder(final Logger logger) { - this.logger = logger; - } - - - // public - // class ObjectEncoder extends MessageToByteEncoder { - // private static final byte[] LENGTH_PLACEHOLDER = new byte[4]; - - // @Override - // protected - // void encode(ChannelHandlerContext ctx, Serializable msg, ByteBuf out) throws Exception { - // int startIdx = out.writerIndex(); - // - // ByteBufOutputStream bout = new ByteBufOutputStream(out); - // ObjectOutputStream oout = null; - // try { - // bout.write(LENGTH_PLACEHOLDER); - // oout = new CompactObjectOutputStream(bout); - // oout.writeObject(msg); - // oout.flush(); - // } finally { - // if (oout != null) { - // oout.close(); - // } - // else { - // bout.close(); - // } - // } - // - // int endIdx = out.writerIndex(); - // - // out.setInt(startIdx, endIdx - startIdx - 4); - // } - - @Override - protected - void encode(final ChannelHandlerContext context, final DnsServerResponse message, final ByteBuf out) throws Exception { - try { - DnsOutput dnsOutput = new DnsOutput(out); - out.retain(); - message.toWire(dnsOutput); - - DatagramPacket packet = new DatagramPacket(out, message.recipient(), message.sender()); - context.channel() - .writeAndFlush(packet); - } catch (Exception e) { - context.fireExceptionCaught(new IOException("Unable to write dns message: " + message, e)); - } - } - - @Override - public - void exceptionCaught(final ChannelHandlerContext context, final Throwable cause) throws Exception { - logger.error("DnsMessageEncoder#exceptionCaught", cause); - super.exceptionCaught(context, cause); - } -} diff --git a/src/dorkbox/network/dns/serverHandlers/DnsServerHandler.java b/src/dorkbox/network/dns/serverHandlers/DnsServerHandler.java deleted file mode 100644 index a8e89808..00000000 --- a/src/dorkbox/network/dns/serverHandlers/DnsServerHandler.java +++ /dev/null @@ -1,88 +0,0 @@ -package dorkbox.network.dns.serverHandlers; - - -import java.util.ArrayList; - -import org.slf4j.Logger; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.records.ARecord; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.channel.ChannelPipeline; - -/** - * - */ -public -class DnsServerHandler extends ChannelInboundHandlerAdapter { - protected final DnsMessageDecoder decoder; - private final Logger logger; - private DnsDecisionHandler decisionHandler; - private DnsMessageEncoder encoder; - - public - DnsServerHandler(final Logger logger) { - this.logger = logger; - - decoder = new DnsMessageDecoder(logger); - decisionHandler = new DnsDecisionHandler(logger); - encoder = new DnsMessageEncoder(logger); - } - - - public - void stop() { - decisionHandler.stop(); - } - - - /** - * Adds a domain name query result, so clients that request the domain name will get the ipAddress - * - * @param domainName the domain name to have results for - * @param @param aRecords the A records (can be multiple) to return for the requested domain name - */ - public - void addARecord(final Name domainName, final ArrayList aRecords) { - decisionHandler.addARecord(domainName, aRecords); - } - - @Override - public final - void channelRegistered(final ChannelHandlerContext context) { - boolean success = false; - try { - initChannel(context.channel()); - context.fireChannelRegistered(); - success = true; - } catch (Throwable t) { - logger.error("Failed to initialize a channel. Closing: {}", context.channel(), t); - } finally { - if (!success) { - context.close(); - } - } - } - - /** - * STEP 1: Channel is first created - */ - protected - void initChannel(final Channel channel) { - ChannelPipeline pipeline = channel.pipeline(); - - /////////////////////// - // DECODE (or upstream) - /////////////////////// - pipeline.addLast("decoder", decoder); - pipeline.addLast("dnsDecision", decisionHandler); - - // ENCODE (or downstream) - ///////////////////////// - pipeline.addLast("encoder", encoder); - // pipeline.addLast("fowarder", new ForwardingHandler(logger)); - // pipeline.addLast("fowarder", new ForwardingHandler(this.config, this.clientChannelFactory)); - } -} diff --git a/src/dorkbox/network/dns/utils/Address.java b/src/dorkbox/network/dns/utils/Address.java deleted file mode 100644 index 5d3eaedb..00000000 --- a/src/dorkbox/network/dns/utils/Address.java +++ /dev/null @@ -1,503 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.utils; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.List; - -import dorkbox.network.DnsClient; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.records.DnsRecord; -import dorkbox.network.dns.records.PTRRecord; -import io.netty.resolver.ResolvedAddressTypes; - -/** - * Routines dealing with IP addresses. Includes functions similar to - * those in the java.net.InetAddress class. - * - * @author Brian Wellington - */ - -public final -class Address { - - public static final int IPv4 = 1; - public static final int IPv6 = 2; - - private - Address() {} - - public static - byte[] parseV4(String s) { - int numDigits; - int currentOctet; - byte[] values = new byte[4]; - int currentValue; - int length = s.length(); - - currentOctet = 0; - currentValue = 0; - numDigits = 0; - for (int i = 0; i < length; i++) { - char c = s.charAt(i); - if (c >= '0' && c <= '9') { - /* Can't have more than 3 digits per octet. */ - if (numDigits == 3) { - return null; - } - /* Octets shouldn't start with 0, unless they are 0. */ - if (numDigits > 0 && currentValue == 0) { - return null; - } - numDigits++; - currentValue *= 10; - currentValue += (c - '0'); - /* 255 is the maximum value for an octet. */ - if (currentValue > 255) { - return null; - } - } - else if (c == '.') { - /* Can't have more than 3 dots. */ - if (currentOctet == 3) { - return null; - } - /* Two consecutive dots are bad. */ - if (numDigits == 0) { - return null; - } - values[currentOctet++] = (byte) currentValue; - currentValue = 0; - numDigits = 0; - } - else { - return null; - } - } - /* Must have 4 octets. */ - if (currentOctet != 3) { - return null; - } - /* The fourth octet can't be empty. */ - if (numDigits == 0) { - return null; - } - values[currentOctet] = (byte) currentValue; - return values; - } - - public static - byte[] parseV6(String s) { - int range = -1; - byte[] data = new byte[16]; - - String[] tokens = s.split(":", -1); - - int first = 0; - int last = tokens.length - 1; - - if (tokens[0].length() == 0) { - // If the first two tokens are empty, it means the string - // started with ::, which is fine. If only the first is - // empty, the string started with :, which is bad. - if (last - first > 0 && tokens[1].length() == 0) { - first++; - } - else { - return null; - } - } - - if (tokens[last].length() == 0) { - // If the last two tokens are empty, it means the string - // ended with ::, which is fine. If only the last is - // empty, the string ended with :, which is bad. - if (last - first > 0 && tokens[last - 1].length() == 0) { - last--; - } - else { - return null; - } - } - - if (last - first + 1 > 8) { - return null; - } - - int i, j; - for (i = first, j = 0; i <= last; i++) { - if (tokens[i].length() == 0) { - if (range >= 0) { - return null; - } - range = j; - continue; - } - - if (tokens[i].indexOf('.') >= 0) { - // An IPv4 address must be the last component - if (i < last) { - return null; - } - // There can't have been more than 6 components. - if (i > 6) { - return null; - } - byte[] v4addr = Address.toByteArray(tokens[i], IPv4); - if (v4addr == null) { - return null; - } - for (int k = 0; k < 4; k++) { - data[j++] = v4addr[k]; - } - break; - } - - try { - for (int k = 0; k < tokens[i].length(); k++) { - char c = tokens[i].charAt(k); - if (Character.digit(c, 16) < 0) { - return null; - } - } - int x = Integer.parseInt(tokens[i], 16); - if (x > 0xFFFF || x < 0) { - return null; - } - data[j++] = (byte) (x >>> 8); - data[j++] = (byte) (x & 0xFF); - } catch (NumberFormatException e) { - return null; - } - } - - if (j < 16 && range < 0) { - return null; - } - - if (range >= 0) { - int empty = 16 - j; - System.arraycopy(data, range, data, range + empty, j - range); - for (i = range; i < range + empty; i++) { - data[i] = 0; - } - } - - return data; - } - - /** - * Convert a string containing an IP address to an array of 4 or 16 integers. - * - * @param s The address, in text format. - * @param family The address family. - * - * @return The address - */ - public static - int[] toArray(String s, int family) { - byte[] byteArray = toByteArray(s, family); - if (byteArray == null) { - return null; - } - int[] intArray = new int[byteArray.length]; - for (int i = 0; i < byteArray.length; i++) { - intArray[i] = byteArray[i] & 0xFF; - } - return intArray; - } - - /** - * Convert a string containing an IPv4 address to an array of 4 integers. - * - * @param s The address, in text format. - * - * @return The address - */ - public static - int[] toArray(String s) { - return toArray(s, IPv4); - } - - /** - * Convert a string containing an IP address to an array of 4 or 16 bytes. - * - * @param s The address, in text format. - * @param family The address family. - * - * @return The address - */ - public static - byte[] toByteArray(String s, int family) { - if (family == IPv4) { - return parseV4(s); - } - else if (family == IPv6) { - return parseV6(s); - } - else { - throw new IllegalArgumentException("unknown address family"); - } - } - - /** - * Determines if a string contains a valid IP address. - * - * @param s The string - * - * @return Whether the string contains a valid IP address - */ - public static - boolean isDottedQuad(String s) { - byte[] address = Address.toByteArray(s, IPv4); - return (address != null); - } - - /** - * Converts a byte array containing an IPv4 address into a dotted quad string. - * - * @param addr The array - * - * @return The string representation - */ - public static - String toDottedQuad(byte[] addr) { - return ((addr[0] & 0xFF) + "." + (addr[1] & 0xFF) + "." + (addr[2] & 0xFF) + "." + (addr[3] & 0xFF)); - } - - /** - * Converts an int array containing an IPv4 address into a dotted quad string. - * - * @param addr The array - * - * @return The string representation - */ - public static - String toDottedQuad(int[] addr) { - return (addr[0] + "." + addr[1] + "." + addr[2] + "." + addr[3]); - } - - private static - List lookupHostName(String name) throws UnknownHostException { - DnsClient client = new DnsClient(); - List resolved = client.resolve(name); - client.stop(); - return resolved; - } - - /** - * Determines the IP address of a host - * - * @param name The hostname to look up - * - * @return The first matching IP address - * - * @throws UnknownHostException The hostname does not have any addresses - */ - public static - InetAddress getByName(String name) throws UnknownHostException { - try { - return getByAddress(name); - } catch (UnknownHostException e) { - List records = lookupHostName(name); - if (records == null) { - return null; - } - - return records.get(0); - } - } - - /** - * Determines all IP address of a host - * - * @param name The hostname to look up - * - * @return All matching IP addresses - * - * @throws UnknownHostException The hostname does not have any addresses - */ - public static - InetAddress[] getAllByName(String name) throws UnknownHostException { - try { - InetAddress addr = getByAddress(name); - return new InetAddress[] {addr}; - } catch (UnknownHostException e) { - List combined = new ArrayList(); - DnsClient client = new DnsClient(); - // ipv4 - client.resolvedAddressTypes(ResolvedAddressTypes.IPV4_ONLY); - List resolved = client.resolve(name); - combined.addAll(resolved); - client.stop(); - - - client = new DnsClient(); - client.resolvedAddressTypes(ResolvedAddressTypes.IPV6_ONLY); - // ipv6 - List resolved2 = client.resolve(name); - combined.addAll(resolved2); - client.stop(); - - - return combined.toArray(new InetAddress[0]); - } - } - - /** - * Converts an address from its string representation to an IP address. - * The address can be either IPv4 or IPv6. - * - * @param addr The address, in string form - * - * @return The IP addresses - * - * @throws UnknownHostException The address is not a valid IP address. - */ - public static - InetAddress getByAddress(String addr) throws UnknownHostException { - byte[] bytes; - bytes = toByteArray(addr, IPv4); - if (bytes != null) { - return InetAddress.getByAddress(addr, bytes); - } - bytes = toByteArray(addr, IPv6); - if (bytes != null) { - return InetAddress.getByAddress(addr, bytes); - } - throw new UnknownHostException("Invalid address: " + addr); - } - - /** - * Converts an address from its string representation to an IP address in - * a particular family. - * - * @param addr The address, in string form - * @param family The address family, either IPv4 or IPv6. - * - * @return The IP addresses - * - * @throws UnknownHostException The address is not a valid IP address in - * the specified address family. - */ - public static - InetAddress getByAddress(String addr, int family) throws UnknownHostException { - if (family != IPv4 && family != IPv6) { - throw new IllegalArgumentException("unknown address family"); - } - byte[] bytes; - bytes = toByteArray(addr, family); - if (bytes != null) { - return InetAddress.getByAddress(addr, bytes); - } - throw new UnknownHostException("Invalid address: " + addr); - } - - /** - * Determines the hostname for an address - * - * @param addr The address to look up - * - * @return The associated host name - * - * @throws UnknownHostException There is no hostname for the address - */ - public static - String getHostName(InetAddress addr) throws UnknownHostException { - Name name = ReverseMap.fromAddress(addr); - - DnsClient client = new DnsClient(); - client.resolvedAddressTypes(ResolvedAddressTypes.IPV4_ONLY); - DnsRecord[] records; - try { - records = client.query(name.toString(true), DnsRecordType.PTR); - } catch (Throwable ignored) { - throw new UnknownHostException("unknown address"); - } finally { - client.stop(); - } - - if (records == null) { - throw new UnknownHostException("unknown address"); - } - - PTRRecord ptr = (PTRRecord) records[0]; - return ptr.getTarget() - .toString(); - } - - /** - * Truncates an address to the specified number of bits. For example, - * truncating the address 10.1.2.3 to 8 bits would yield 10.0.0.0. - * - * @param address The source address - * @param maskLength The number of bits to truncate the address to. - */ - public static - InetAddress truncate(InetAddress address, int maskLength) { - int family = familyOf(address); - int maxMaskLength = addressLength(family) * 8; - if (maskLength < 0 || maskLength > maxMaskLength) { - throw new IllegalArgumentException("invalid mask length"); - } - if (maskLength == maxMaskLength) { - return address; - } - byte[] bytes = address.getAddress(); - for (int i = maskLength / 8 + 1; i < bytes.length; i++) { - bytes[i] = 0; - } - int maskBits = maskLength % 8; - int bitmask = 0; - for (int i = 0; i < maskBits; i++) { - bitmask |= (1 << (7 - i)); - } - bytes[maskLength / 8] &= bitmask; - try { - return InetAddress.getByAddress(bytes); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("invalid address"); - } - } - - /** - * Returns the family of an InetAddress. - * - * @param address The supplied address. - * - * @return The family, either IPv4 or IPv6. - */ - public static - int familyOf(InetAddress address) { - if (address instanceof Inet4Address) { - return IPv4; - } - if (address instanceof Inet6Address) { - return IPv6; - } - throw new IllegalArgumentException("unknown address family"); - } - - /** - * Returns the length of an address in a particular family. - * - * @param family The address family, either IPv4 or IPv6. - * - * @return The length of addresses in that family. - */ - public static - int addressLength(int family) { - if (family == IPv4) { - return 4; - } - if (family == IPv6) { - return 16; - } - throw new IllegalArgumentException("unknown address family"); - } -} diff --git a/src/dorkbox/network/dns/utils/FormattedTime.java b/src/dorkbox/network/dns/utils/FormattedTime.java deleted file mode 100644 index 50043e81..00000000 --- a/src/dorkbox/network/dns/utils/FormattedTime.java +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.utils; - -/** - * Routines for converting time values to and from YYYYMMDDHHMMSS format. - * - * @author Brian Wellington - */ - -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.TimeZone; - -import dorkbox.network.dns.exceptions.TextParseException; - -public final -class FormattedTime { - - private static NumberFormat w2, w4; - - static { - w2 = new DecimalFormat(); - w2.setMinimumIntegerDigits(2); - - w4 = new DecimalFormat(); - w4.setMinimumIntegerDigits(4); - w4.setGroupingUsed(false); - } - - private - FormattedTime() {} - - /** - * Converts a Date into a formatted string. - * - * @param date The Date to convert. - * - * @return The formatted string. - */ - public static - String format(Date date) { - Calendar c = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - StringBuilder sb = new StringBuilder(); - - c.setTime(date); - sb.append(w4.format(c.get(Calendar.YEAR))); - sb.append(w2.format(c.get(Calendar.MONTH) + 1)); - sb.append(w2.format(c.get(Calendar.DAY_OF_MONTH))); - sb.append(w2.format(c.get(Calendar.HOUR_OF_DAY))); - sb.append(w2.format(c.get(Calendar.MINUTE))); - sb.append(w2.format(c.get(Calendar.SECOND))); - return sb.toString(); - } - - /** - * Parses a formatted time string into a Date. - * - * @param s The string, in the form YYYYMMDDHHMMSS. - * - * @return The Date object. - * - * @throws TextParseException The string was invalid. - */ - public static - Date parse(String s) throws TextParseException { - if (s.length() != 14) { - throw new TextParseException("Invalid time encoding: " + s); - } - - Calendar c = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - c.clear(); - try { - int year = Integer.parseInt(s.substring(0, 4)); - int month = Integer.parseInt(s.substring(4, 6)) - 1; - int date = Integer.parseInt(s.substring(6, 8)); - int hour = Integer.parseInt(s.substring(8, 10)); - int minute = Integer.parseInt(s.substring(10, 12)); - int second = Integer.parseInt(s.substring(12, 14)); - c.set(year, month, date, hour, minute, second); - } catch (NumberFormatException e) { - throw new TextParseException("Invalid time encoding: " + s); - } - return c.getTime(); - } - -} diff --git a/src/dorkbox/network/dns/utils/Options.java b/src/dorkbox/network/dns/utils/Options.java deleted file mode 100644 index c6dcdc08..00000000 --- a/src/dorkbox/network/dns/utils/Options.java +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.utils; - -import java.util.StringTokenizer; - -import com.esotericsoftware.kryo.util.ObjectMap; - -/** - * Boolean options:
- * bindttl - Print TTLs in BIND format
- * multiline - Print records in multiline format
- * noprintin - Don't print the class of a record if it's IN
- * verbose - Turn on general debugging statements
- * verbosemsg - Print all messages sent or received by SimpleResolver
- * verbosecompression - Print messages related to name compression
- * verbosesec - Print messages related to signature verification
- * verbosecache - Print messages related to cache lookups
- *
- * Valued options:
- * tsigfudge=n - Sets the default TSIG fudge value (in seconds)
- * sig0validity=n - Sets the default SIG(0) validity period (in seconds)
- * - * @author Brian Wellington - */ - -public final -class Options { - - private static ObjectMap table; - - static { - try { - refresh(); - } catch (SecurityException ignored) { - } - } - - private - Options() {} - - public static - void refresh() { - String s = System.getProperty("dnsjava.options"); - if (s != null) { - StringTokenizer st = new StringTokenizer(s, ","); - while (st.hasMoreTokens()) { - String token = st.nextToken(); - int index = token.indexOf('='); - if (index == -1) { - set(token); - } - else { - String option = token.substring(0, index); - String value = token.substring(index + 1); - set(option, value); - } - } - } - } - - /** - * Sets an option to "true" - */ - public static - void set(String option) { - if (table == null) { - table = new ObjectMap(); - } - - table.put(option.toLowerCase(), "true"); - } - - /** - * Sets an option to the the supplied value - */ - public static - void set(String option, String value) { - if (table == null) { - table = new ObjectMap(); - } - table.put(option.toLowerCase(), value.toLowerCase()); - } - - /** - * Clears all defined options - */ - public static - void clear() { - table = null; - } - - /** - * Removes an option - */ - public static - void unset(String option) { - if (table == null) { - return; - } - table.remove(option.toLowerCase()); - } - - /** - * Checks if an option is defined - */ - public static - boolean check(String option) { - if (table == null) { - return false; - } - - return (table.get(option.toLowerCase()) != null); - } - - /** - * Returns the value of an option as an integer, or -1 if not defined. - */ - public static - int intValue(String option) { - String s = value(option); - if (s != null) { - try { - int val = Integer.parseInt(s); - if (val > 0) { - return (val); - } - } catch (NumberFormatException ignored) { - } - } - - return -1; - } - - /** - * Returns the value of an option - */ - public static - String value(String option) { - if (table == null) { - return null; - } - - return ((String) table.get(option.toLowerCase())); - } -} diff --git a/src/dorkbox/network/dns/utils/ReverseMap.java b/src/dorkbox/network/dns/utils/ReverseMap.java deleted file mode 100644 index 9c26a2b3..00000000 --- a/src/dorkbox/network/dns/utils/ReverseMap.java +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.utils; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.exceptions.TextParseException; - -/** - * A set functions designed to deal with DNS names used in reverse mappings. - * For the IPv4 address a.b.c.d, the reverse map name is d.c.b.a.in-addr.arpa. - * For an IPv6 address, the reverse map name is ...ip6.arpa. - * - * @author Brian Wellington - */ - -public final -class ReverseMap { - - private static Name inaddr4 = Name.fromConstantString("in-addr.arpa."); - private static Name inaddr6 = Name.fromConstantString("ip6.arpa."); - - /* Otherwise the class could be instantiated */ - private - ReverseMap() {} - - /** - * Creates a reverse map name corresponding to an address contained in - * an array of 4 integers between 0 and 255 (for an IPv4 address) or 16 - * integers between 0 and 255 (for an IPv6 address). - * - * @param addr The address from which to build a name. - * - * @return The name corresponding to the address in the reverse map. - */ - public static - Name fromAddress(int[] addr) { - byte[] bytes = new byte[addr.length]; - for (int i = 0; i < addr.length; i++) { - if (addr[i] < 0 || addr[i] > 0xFF) { - throw new IllegalArgumentException("array must " + "contain values " + "between 0 and 255"); - } - bytes[i] = (byte) addr[i]; - } - return fromAddress(bytes); - } - - /** - * Creates a reverse map name corresponding to an address contained in - * an array of 4 bytes (for an IPv4 address) or 16 bytes (for an IPv6 address). - * - * @param addr The address from which to build a name. - * - * @return The name corresponding to the address in the reverse map. - */ - public static - Name fromAddress(byte[] addr) { - if (addr.length != 4 && addr.length != 16) { - throw new IllegalArgumentException("array must contain " + "4 or 16 elements"); - } - - StringBuilder sb = new StringBuilder(); - if (addr.length == 4) { - for (int i = addr.length - 1; i >= 0; i--) { - sb.append(addr[i] & 0xFF); - if (i > 0) { - sb.append("."); - } - } - } - else { - int[] nibbles = new int[2]; - for (int i = addr.length - 1; i >= 0; i--) { - nibbles[0] = (addr[i] & 0xFF) >> 4; - nibbles[1] = (addr[i] & 0xFF) & 0xF; - for (int j = nibbles.length - 1; j >= 0; j--) { - sb.append(Integer.toHexString(nibbles[j])); - if (i > 0 || j > 0) { - sb.append("."); - } - } - } - } - - try { - if (addr.length == 4) { - return Name.fromString(sb.toString(), inaddr4); - } - else { - return Name.fromString(sb.toString(), inaddr6); - } - } catch (TextParseException e) { - throw new IllegalStateException("name cannot be invalid"); - } - } - - /** - * Creates a reverse map name corresponding to an address contained in - * an InetAddress. - * - * @param addr The address from which to build a name. - * - * @return The name corresponding to the address in the reverse map. - */ - public static - Name fromAddress(InetAddress addr) { - return fromAddress(addr.getAddress()); - } - - /** - * Creates a reverse map name corresponding to an address contained in - * a String. - * - * @param addr The address from which to build a name. - * - * @return The name corresponding to the address in the reverse map. - * - * @throws UnknownHostException The string does not contain a valid address. - */ - public static - Name fromAddress(String addr, int family) throws UnknownHostException { - byte[] array = Address.toByteArray(addr, family); - if (array == null) { - throw new UnknownHostException("Invalid IP address"); - } - return fromAddress(array); - } - - /** - * Creates a reverse map name corresponding to an address contained in - * a String. - * - * @param addr The address from which to build a name. - * - * @return The name corresponding to the address in the reverse map. - * - * @throws UnknownHostException The string does not contain a valid address. - */ - public static - Name fromAddress(String addr) throws UnknownHostException { - byte[] array = Address.toByteArray(addr, Address.IPv4); - if (array == null) { - array = Address.toByteArray(addr, Address.IPv6); - } - if (array == null) { - throw new UnknownHostException("Invalid IP address"); - } - return fromAddress(array); - } - -} diff --git a/src/dorkbox/network/dns/utils/Tokenizer.java b/src/dorkbox/network/dns/utils/Tokenizer.java deleted file mode 100644 index 34dbcac4..00000000 --- a/src/dorkbox/network/dns/utils/Tokenizer.java +++ /dev/null @@ -1,888 +0,0 @@ -// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org) -// -// Copyright (C) 2003-2004 Nominum, Inc. -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR ANY -// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -// OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// - -package dorkbox.network.dns.utils; - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.PushbackInputStream; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.exceptions.RelativeNameException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.records.TTL; -import dorkbox.util.Base64Fast; - -/** - * Tokenizer is used to parse DNS records and zones from text format, - * - * @author Brian Wellington - * @author Bob Halley - */ - -public -class Tokenizer { - private static final char[] VALID = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); - private static final int[] INTERNAL = new int[256]; - - static { - Arrays.fill(INTERNAL, -1); - for (int i = 0, iS = VALID.length; i < iS; i++) { - INTERNAL[VALID[i]] = 1; - } - INTERNAL['='] = 1; - } - - - private static String delim = " \t\n;()\""; - private static String quotes = "\""; - - /** - * End of file - */ - public static final int EOF = 0; - - /** - * End of line - */ - public static final int EOL = 1; - - /** - * Whitespace; only returned when wantWhitespace is set - */ - public static final int WHITESPACE = 2; - - /** - * An identifier (unquoted string) - */ - public static final int IDENTIFIER = 3; - - /** - * A quoted string - */ - public static final int QUOTED_STRING = 4; - - /** - * A comment; only returned when wantComment is set - */ - public static final int COMMENT = 5; - - private PushbackInputStream is; - private boolean ungottenToken; - private int multiline; - private boolean quoting; - private String delimiters; - private Token current; - private StringBuilder sb; - private boolean wantClose; - - private String filename; - private int line; - - - public static - class Token { - /** - * The type of token. - */ - public int type; - - /** - * The value of the token, or null for tokens without values. - */ - public String value; - - private - Token() { - type = -1; - value = null; - } - - private - Token set(int type, StringBuilder value) { - if (type < 0) { - throw new IllegalArgumentException(); - } - this.type = type; - this.value = value == null ? null : value.toString(); - return this; - } - - /** - * Converts the token to a string containing a representation useful - * for debugging. - */ - public - String toString() { - switch (type) { - case EOF: - return ""; - case EOL: - return ""; - case WHITESPACE: - return ""; - case IDENTIFIER: - return ""; - case QUOTED_STRING: - return ""; - case COMMENT: - return ""; - default: - return ""; - } - } - - /** - * Indicates whether this token contains a string. - */ - public - boolean isString() { - return (type == IDENTIFIER || type == QUOTED_STRING); - } - - /** - * Indicates whether this token contains an EOL or EOF. - */ - public - boolean isEOL() { - return (type == EOL || type == EOF); - } - } - - - public static - class TokenizerException extends TextParseException { - String message; - - public - TokenizerException(String filename, int line, String message) { - super(filename + ":" + line + ": " + message); - this.message = message; - } - - public - String getBaseMessage() { - return message; - } - } - - /** - * Creates a Tokenizer from a string. - * - * @param s The String to tokenize. - */ - public - Tokenizer(String s) { - this(new ByteArrayInputStream(s.getBytes())); - } - - /** - * Creates a Tokenizer from an arbitrary input stream. - * - * @param is The InputStream to tokenize. - */ - public - Tokenizer(InputStream is) { - if (!(is instanceof BufferedInputStream)) { - is = new BufferedInputStream(is); - } - this.is = new PushbackInputStream(is, 2); - ungottenToken = false; - multiline = 0; - quoting = false; - delimiters = delim; - current = new Token(); - sb = new StringBuilder(); - filename = ""; - line = 1; - } - - /** - * Creates a Tokenizer from a file. - * - * @param f The File to tokenize. - */ - public - Tokenizer(File f) throws FileNotFoundException { - this(new FileInputStream(f)); - wantClose = true; - filename = f.getName(); - } - - /** - * Gets the next token from a tokenizer and converts it to a string. - * - * @return The next token in the stream, as a string. - * - * @throws TextParseException The input was invalid or not a string. - * @throws IOException An I/O error occurred. - */ - public - String getString() throws IOException { - Token next = get(); - if (!next.isString()) { - throw exception("expected a string"); - } - return next.value; - } - - /** - * Gets the next token from a tokenizer, ignoring whitespace and comments. - * - * @return The next token in the stream. - * - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ - public - Token get() throws IOException { - return get(false, false); - } - - /** - * Gets the next token from a tokenizer. - * - * @param wantWhitespace If true, leading whitespace will be returned as a - * token. - * @param wantComment If true, comments are returned as tokens. - * - * @return The next token in the stream. - * - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ - public - Token get(boolean wantWhitespace, boolean wantComment) throws IOException { - int type; - int c; - - if (ungottenToken) { - ungottenToken = false; - if (current.type == WHITESPACE) { - if (wantWhitespace) { - return current; - } - } - else if (current.type == COMMENT) { - if (wantComment) { - return current; - } - } - else { - if (current.type == EOL) { - line++; - } - return current; - } - } - int skipped = skipWhitespace(); - if (skipped > 0 && wantWhitespace) { - return current.set(WHITESPACE, null); - } - type = IDENTIFIER; - sb.setLength(0); - while (true) { - c = getChar(); - if (c == -1 || delimiters.indexOf(c) != -1) { - if (c == -1) { - if (quoting) { - throw exception("EOF in " + "quoted string"); - } - else if (sb.length() == 0) { - return current.set(EOF, null); - } - else { - return current.set(type, sb); - } - } - if (sb.length() == 0 && type != QUOTED_STRING) { - if (c == '(') { - multiline++; - skipWhitespace(); - continue; - } - else if (c == ')') { - if (multiline <= 0) { - throw exception("invalid " + "close " + "parenthesis"); - } - multiline--; - skipWhitespace(); - continue; - } - else if (c == '"') { - if (!quoting) { - quoting = true; - delimiters = quotes; - type = QUOTED_STRING; - } - else { - quoting = false; - delimiters = delim; - skipWhitespace(); - } - continue; - } - else if (c == '\n') { - return current.set(EOL, null); - } - else if (c == ';') { - while (true) { - c = getChar(); - if (c == '\n' || c == -1) { - break; - } - sb.append((char) c); - } - if (wantComment) { - ungetChar(c); - return current.set(COMMENT, sb); - } - else if (c == -1 && type != QUOTED_STRING) { - checkUnbalancedParens(); - return current.set(EOF, null); - } - else if (multiline > 0) { - skipWhitespace(); - sb.setLength(0); - continue; - } - else { - return current.set(EOL, null); - } - } - else { - throw new IllegalStateException(); - } - } - else { - ungetChar(c); - } - break; - } - else if (c == '\\') { - c = getChar(); - if (c == -1) { - throw exception("unterminated escape sequence"); - } - sb.append('\\'); - } - else if (quoting && c == '\n') { - throw exception("newline in quoted string"); - } - sb.append((char) c); - } - if (sb.length() == 0 && type != QUOTED_STRING) { - checkUnbalancedParens(); - return current.set(EOF, null); - } - return current.set(type, sb); - } - - private - int skipWhitespace() throws IOException { - int skipped = 0; - while (true) { - int c = getChar(); - if (c != ' ' && c != '\t') { - if (!(c == '\n' && multiline > 0)) { - ungetChar(c); - return skipped; - } - } - skipped++; - } - } - - private - int getChar() throws IOException { - int c = is.read(); - if (c == '\r') { - int next = is.read(); - if (next != '\n') { - is.unread(next); - } - c = '\n'; - } - if (c == '\n') { - line++; - } - return c; - } - - private - void ungetChar(int c) throws IOException { - if (c == -1) { - return; - } - is.unread(c); - if (c == '\n') { - line--; - } - } - - private - void checkUnbalancedParens() throws TextParseException { - if (multiline > 0) { - throw exception("unbalanced parentheses"); - } - } - - /** - * Creates an exception which includes the current state in the error message - * - * @param s The error message to include. - * - * @return The exception to be thrown - */ - public - TextParseException exception(String s) { - return new TokenizerException(filename, line, s); - } - - /** - * Gets the next token from a tokenizer, ensures it is an unquoted string, - * and converts it to a string. - * - * @return The next token in the stream, as a string. - * - * @throws TextParseException The input was invalid or not an unquoted string. - * @throws IOException An I/O error occurred. - */ - public - String getIdentifier() throws IOException { - return _getIdentifier("an identifier"); - } - - private - String _getIdentifier(String expected) throws IOException { - Token next = get(); - if (next.type != IDENTIFIER) { - throw exception("expected " + expected); - } - return next.value; - } - - /** - * Gets the next token from a tokenizer and converts it to an unsigned 32 bit - * integer. - * - * @return The next token in the stream, as an unsigned 32 bit integer. - * - * @throws TextParseException The input was invalid or not an unsigned 32 - * bit integer. - * @throws IOException An I/O error occurred. - */ - public - long getUInt32() throws IOException { - long l = getLong(); - if (l < 0 || l > 0xFFFFFFFFL) { - throw exception("expected an 32 bit unsigned integer"); - } - return l; - } - - /** - * Gets the next token from a tokenizer and converts it to a long. - * - * @return The next token in the stream, as a long. - * - * @throws TextParseException The input was invalid or not a long. - * @throws IOException An I/O error occurred. - */ - public - long getLong() throws IOException { - String next = _getIdentifier("an integer"); - if (!Character.isDigit(next.charAt(0))) { - throw exception("expected an integer"); - } - try { - return Long.parseLong(next); - } catch (NumberFormatException e) { - throw exception("expected an integer"); - } - } - - /** - * Gets the next token from a tokenizer and converts it to an unsigned 16 bit - * integer. - * - * @return The next token in the stream, as an unsigned 16 bit integer. - * - * @throws TextParseException The input was invalid or not an unsigned 16 - * bit integer. - * @throws IOException An I/O error occurred. - */ - public - int getUInt16() throws IOException { - long l = getLong(); - if (l < 0 || l > 0xFFFFL) { - throw exception("expected an 16 bit unsigned integer"); - } - return (int) l; - } - - /** - * Gets the next token from a tokenizer and converts it to an unsigned 8 bit - * integer. - * - * @return The next token in the stream, as an unsigned 8 bit integer. - * - * @throws TextParseException The input was invalid or not an unsigned 8 - * bit integer. - * @throws IOException An I/O error occurred. - */ - public - int getUInt8() throws IOException { - long l = getLong(); - if (l < 0 || l > 0xFFL) { - throw exception("expected an 8 bit unsigned integer"); - } - return (int) l; - } - - /** - * Gets the next token from a tokenizer and parses it as a TTL. - * - * @return The next token in the stream, as an unsigned 32 bit integer. - * - * @throws TextParseException The input was not valid. - * @throws IOException An I/O error occurred. - * @see TTL - */ - public - long getTTL() throws IOException { - String next = _getIdentifier("a TTL value"); - try { - return TTL.parseTTL(next); - } catch (NumberFormatException e) { - throw exception("expected a TTL value"); - } - } - - /** - * Gets the next token from a tokenizer and parses it as if it were a TTL. - * - * @return The next token in the stream, as an unsigned 32 bit integer. - * - * @throws TextParseException The input was not valid. - * @throws IOException An I/O error occurred. - * @see TTL - */ - public - long getTTLLike() throws IOException { - String next = _getIdentifier("a TTL-like value"); - try { - return TTL.parse(next, false); - } catch (NumberFormatException e) { - throw exception("expected a TTL-like value"); - } - } - - /** - * Gets the next token from a tokenizer and converts it to a name. - * - * @param origin The origin to append to relative names. - * - * @return The next token in the stream, as a name. - * - * @throws TextParseException The input was invalid or not a valid name. - * @throws IOException An I/O error occurred. - * @throws RelativeNameException The parsed name was relative, even with the - * origin. - * @see Name - */ - public - Name getName(Name origin) throws IOException { - String next = _getIdentifier("a name"); - try { - Name name = Name.fromString(next, origin); - if (!name.isAbsolute()) { - throw new RelativeNameException(name); - } - return name; - } catch (TextParseException e) { - throw exception(e.getMessage()); - } - } - - /** - * Gets the next token from a tokenizer and converts it to a byte array - * containing an IP address. - * - * @param family The address family. - * - * @return The next token in the stream, as an byte array representing an IP - * address. - * - * @throws TextParseException The input was invalid or not a valid address. - * @throws IOException An I/O error occurred. - * @see Address - */ - public - byte[] getAddressBytes(int family) throws IOException { - String next = _getIdentifier("an address"); - byte[] bytes = Address.toByteArray(next, family); - if (bytes == null) { - throw exception("Invalid address: " + next); - } - return bytes; - } - - /** - * Gets the next token from a tokenizer and converts it to an IP Address. - * - * @param family The address family. - * - * @return The next token in the stream, as an InetAddress - * - * @throws TextParseException The input was invalid or not a valid address. - * @throws IOException An I/O error occurred. - * @see Address - */ - public - InetAddress getAddress(int family) throws IOException { - String next = _getIdentifier("an address"); - try { - return Address.getByAddress(next, family); - } catch (UnknownHostException e) { - throw exception(e.getMessage()); - } - } - - /** - * Gets the next token from a tokenizer, which must be an EOL or EOF. - * - * @throws TextParseException The input was invalid or not an EOL or EOF token. - * @throws IOException An I/O error occurred. - */ - public - void getEOL() throws IOException { - Token next = get(); - if (next.type != EOL && next.type != EOF) { - throw exception("expected EOL or EOF"); - } - } - - /** - * Gets the remaining string tokens until an EOL/EOF is seen, concatenates - * them together, and converts the base64 encoded data to a byte array. - * - * @return The byte array containing the decoded strings, or null if there - * were no strings to decode. - * - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ - public - byte[] getBase64() throws IOException { - return getBase64(false); - } - - /** - * Gets the remaining string tokens until an EOL/EOF is seen, concatenates - * them together, and converts the base64 encoded data to a byte array. - * - * @param required If true, an exception will be thrown if no strings remain; - * otherwise null be be returned. - * - * @return The byte array containing the decoded strings, or null if there - * were no strings to decode. - * - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ - public - byte[] getBase64(boolean required) throws IOException { - String s = remainingStrings(); - if (s == null) { - if (required) { - throw exception("expected base64 encoded string"); - } - else { - return null; - } - } - - // have to validate the base-64 encoded strings first. - char[] chars = s.toCharArray(); - for (char aChar : chars) { - if (aChar > 256 || INTERNAL[aChar] != 1) { - // not valid - throw new TextParseException("Invalid base64 character!"); - } - } - - byte[] array = Base64Fast.decode2(s); - if (array == null) { - throw exception("invalid base64 encoding"); - } - - return array; - } - - /** - * Returns a concatenation of the remaining strings from a Tokenizer. - */ - private - String remainingStrings() throws IOException { - StringBuilder buffer = null; - while (true) { - Tokenizer.Token t = get(); - if (!t.isString()) { - break; - } - if (buffer == null) { - buffer = new StringBuilder(); - } - buffer.append(t.value); - } - unget(); - if (buffer == null) { - return null; - } - return buffer.toString(); - } - - /** - * Returns a token to the stream, so that it will be returned by the next call - * to get(). - * - * @throws IllegalStateException There are already ungotten tokens. - */ - public - void unget() { - if (ungottenToken) { - throw new IllegalStateException("Cannot unget multiple tokens"); - } - if (current.type == EOL) { - line--; - } - ungottenToken = true; - } - - /** - * Gets the remaining string tokens until an EOL/EOF is seen, concatenates - * them together, and converts the hex encoded data to a byte array. - * - * @return The byte array containing the decoded strings, or null if there - * were no strings to decode. - * - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ - public - byte[] getHex() throws IOException { - return getHex(false); - } - - /** - * Gets the remaining string tokens until an EOL/EOF is seen, concatenates - * them together, and converts the hex encoded data to a byte array. - * - * @param required If true, an exception will be thrown if no strings remain; - * otherwise null be be returned. - * - * @return The byte array containing the decoded strings, or null if there - * were no strings to decode. - * - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ - public - byte[] getHex(boolean required) throws IOException { - String s = remainingStrings(); - if (s == null) { - if (required) { - throw exception("expected hex encoded string"); - } - else { - return null; - } - } - byte[] array = base16.fromString(s); - if (array == null) { - throw exception("invalid hex encoding"); - } - return array; - } - - /** - * Gets the next token from a tokenizer and decodes it as hex. - * - * @return The byte array containing the decoded string. - * - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ - public - byte[] getHexString() throws IOException { - String next = _getIdentifier("a hex string"); - byte[] array = base16.fromString(next); - if (array == null) { - throw exception("invalid hex encoding"); - } - return array; - } - - /** - * Gets the next token from a tokenizer and decodes it as base32. - * - * @param b32 The base32 context to decode with. - * - * @return The byte array containing the decoded string. - * - * @throws TextParseException The input was invalid. - * @throws IOException An I/O error occurred. - */ - public - byte[] getBase32String(base32 b32) throws IOException { - String next = _getIdentifier("a base32 string"); - byte[] array = b32.fromString(next); - if (array == null) { - throw exception("invalid base32 encoding"); - } - return array; - } - - /** - * Closes any files opened by this tokenizer. - */ - public - void close() { - if (wantClose) { - try { - is.close(); - } catch (IOException e) { - } - } - } - - @Override - protected - void finalize() { - close(); - } - -} diff --git a/src/dorkbox/network/dns/utils/base16.java b/src/dorkbox/network/dns/utils/base16.java deleted file mode 100644 index b79fa80f..00000000 --- a/src/dorkbox/network/dns/utils/base16.java +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.utils; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * Routines for converting between Strings of hex-encoded data and arrays of - * binary data. This is not actually used by DNS. - * - * @author Brian Wellington - */ - -public -class base16 { - - private static final String Base16 = "0123456789ABCDEF"; - - private - base16() {} - - /** - * Convert binary data to a hex-encoded String - * - * @param b An array containing binary data - * - * @return A String containing the encoded data - */ - public static - String toString(byte[] b) { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - for (int i = 0; i < b.length; i++) { - short value = (short) (b[i] & 0xFF); - byte high = (byte) (value >> 4); - byte low = (byte) (value & 0xF); - os.write(Base16.charAt(high)); - os.write(Base16.charAt(low)); - } - return new String(os.toByteArray()); - } - - /** - * Convert a hex-encoded String to binary data - * - * @param str A String containing the encoded data - * - * @return An array containing the binary data, or null if the string is invalid - */ - public static - byte[] fromString(String str) { - ByteArrayOutputStream bs = new ByteArrayOutputStream(); - byte[] raw = str.getBytes(); - for (int i = 0; i < raw.length; i++) { - if (!Character.isWhitespace((char) raw[i])) { - bs.write(raw[i]); - } - } - byte[] in = bs.toByteArray(); - if (in.length % 2 != 0) { - return null; - } - - bs.reset(); - DataOutputStream ds = new DataOutputStream(bs); - - for (int i = 0; i < in.length; i += 2) { - byte high = (byte) Base16.indexOf(Character.toUpperCase((char) in[i])); - byte low = (byte) Base16.indexOf(Character.toUpperCase((char) in[i + 1])); - try { - ds.writeByte((high << 4) + low); - } catch (IOException e) { - } - } - return bs.toByteArray(); - } - -} diff --git a/src/dorkbox/network/dns/utils/base32.java b/src/dorkbox/network/dns/utils/base32.java deleted file mode 100644 index 47d7c64c..00000000 --- a/src/dorkbox/network/dns/utils/base32.java +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) - -package dorkbox.network.dns.utils; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * Routines for converting between Strings of base32-encoded data and arrays - * of binary data. This currently supports the base32 and base32hex alphabets - * specified in RFC 4648, sections 6 and 7. - * - * @author Brian Wellington - */ - -public -class base32 { - - private String alphabet; - - - private boolean padding, lowercase; - - - public static - class Alphabet { - public static final String BASE32 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567="; - public static final String BASE32HEX = "0123456789ABCDEFGHIJKLMNOPQRSTUV="; - private - Alphabet() {} - } - - /** - * Creates an object that can be used to do base32 conversions. - * - * @param alphabet Which alphabet should be used - * @param padding Whether padding should be used - * @param lowercase Whether lowercase characters should be used. - * default parameters (The standard base32 alphabet, no padding, uppercase) - */ - public - base32(String alphabet, boolean padding, boolean lowercase) { - this.alphabet = alphabet; - this.padding = padding; - this.lowercase = lowercase; - } - - /** - * Convert binary data to a base32-encoded String - * - * @param b An array containing binary data - * - * @return A String containing the encoded data - */ - public - String toString(byte[] b) { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - - for (int i = 0; i < (b.length + 4) / 5; i++) { - short s[] = new short[5]; - int t[] = new int[8]; - - int blocklen = 5; - for (int j = 0; j < 5; j++) { - if ((i * 5 + j) < b.length) { - s[j] = (short) (b[i * 5 + j] & 0xFF); - } - else { - s[j] = 0; - blocklen--; - } - } - int padlen = blockLenToPadding(blocklen); - - // convert the 5 byte block into 8 characters (values 0-31). - - // upper 5 bits from first byte - t[0] = (byte) ((s[0] >> 3) & 0x1F); - // lower 3 bits from 1st byte, upper 2 bits from 2nd. - t[1] = (byte) (((s[0] & 0x07) << 2) | ((s[1] >> 6) & 0x03)); - // bits 5-1 from 2nd. - t[2] = (byte) ((s[1] >> 1) & 0x1F); - // lower 1 bit from 2nd, upper 4 from 3rd - t[3] = (byte) (((s[1] & 0x01) << 4) | ((s[2] >> 4) & 0x0F)); - // lower 4 from 3rd, upper 1 from 4th. - t[4] = (byte) (((s[2] & 0x0F) << 1) | ((s[3] >> 7) & 0x01)); - // bits 6-2 from 4th - t[5] = (byte) ((s[3] >> 2) & 0x1F); - // lower 2 from 4th, upper 3 from 5th; - t[6] = (byte) (((s[3] & 0x03) << 3) | ((s[4] >> 5) & 0x07)); - // lower 5 from 5th; - t[7] = (byte) (s[4] & 0x1F); - - // write out the actual characters. - for (int j = 0; j < t.length - padlen; j++) { - char c = alphabet.charAt(t[j]); - if (lowercase) { - c = Character.toLowerCase(c); - } - os.write(c); - } - - // write out the padding (if any) - if (padding) { - for (int j = t.length - padlen; j < t.length; j++) { - os.write('='); - } - } - } - - return new String(os.toByteArray()); - } - - static private - int blockLenToPadding(int blocklen) { - switch (blocklen) { - case 1: - return 6; - case 2: - return 4; - case 3: - return 3; - case 4: - return 1; - case 5: - return 0; - default: - return -1; - } - } - - /** - * Convert a base32-encoded String to binary data - * - * @param str A String containing the encoded data - * - * @return An array containing the binary data, or null if the string is invalid - */ - public - byte[] fromString(String str) { - ByteArrayOutputStream bs = new ByteArrayOutputStream(); - byte[] raw = str.getBytes(); - for (int i = 0; i < raw.length; i++) { - char c = (char) raw[i]; - if (!Character.isWhitespace(c)) { - c = Character.toUpperCase(c); - bs.write((byte) c); - } - } - - if (padding) { - if (bs.size() % 8 != 0) { - return null; - } - } - else { - while (bs.size() % 8 != 0) { - bs.write('='); - } - } - - byte[] in = bs.toByteArray(); - - bs.reset(); - DataOutputStream ds = new DataOutputStream(bs); - - for (int i = 0; i < in.length / 8; i++) { - short[] s = new short[8]; - int[] t = new int[5]; - - int padlen = 8; - for (int j = 0; j < 8; j++) { - char c = (char) in[i * 8 + j]; - if (c == '=') { - break; - } - s[j] = (short) alphabet.indexOf(in[i * 8 + j]); - if (s[j] < 0) { - return null; - } - padlen--; - } - int blocklen = paddingToBlockLen(padlen); - if (blocklen < 0) { - return null; - } - - // all 5 bits of 1st, high 3 (of 5) of 2nd - t[0] = (s[0] << 3) | s[1] >> 2; - // lower 2 of 2nd, all 5 of 3rd, high 1 of 4th - t[1] = ((s[1] & 0x03) << 6) | (s[2] << 1) | (s[3] >> 4); - // lower 4 of 4th, high 4 of 5th - t[2] = ((s[3] & 0x0F) << 4) | ((s[4] >> 1) & 0x0F); - // lower 1 of 5th, all 5 of 6th, high 2 of 7th - t[3] = (s[4] << 7) | (s[5] << 2) | (s[6] >> 3); - // lower 3 of 7th, all of 8th - t[4] = ((s[6] & 0x07) << 5) | s[7]; - - try { - for (int j = 0; j < blocklen; j++) { - ds.writeByte((byte) (t[j] & 0xFF)); - } - } catch (IOException e) { - } - } - - return bs.toByteArray(); - } - - static private - int paddingToBlockLen(int padlen) { - switch (padlen) { - case 6: - return 1; - case 4: - return 2; - case 3: - return 3; - case 1: - return 4; - case 0: - return 5; - default: - return -1; - } - } - -} diff --git a/src/dorkbox/network/dns/zone/AbstractZone.java b/src/dorkbox/network/dns/zone/AbstractZone.java deleted file mode 100644 index 810243b5..00000000 --- a/src/dorkbox/network/dns/zone/AbstractZone.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.zone; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; - -public abstract class AbstractZone implements Zone { - - protected ZoneType type; - protected int dnsClass; - protected Name name; - - public AbstractZone(ZoneType type, Name name) { - this(type, DnsClass.IN, name); - } - - public AbstractZone(ZoneType type, int dnsClass, Name name) { - this.type = type; - this.dnsClass = dnsClass; - this.name = name; - } - - @Override - public ZoneType type() { - return this.type; - } - - @Override - public int dnsClass() { - return this.dnsClass; - } - - @Override - public Name name() { - return this.name; - } - -} diff --git a/src/dorkbox/network/dns/zone/ForwardZone.java b/src/dorkbox/network/dns/zone/ForwardZone.java deleted file mode 100644 index 895e7d4b..00000000 --- a/src/dorkbox/network/dns/zone/ForwardZone.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.zone; - -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.List; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.server.Response; - -public class ForwardZone extends AbstractZone { - - protected List forwarders = new ArrayList(); - - public ForwardZone(Name name) { - super(ZoneType.forward, name); - } - - public ForwardZone(int dnsclass, Name name) { - super(ZoneType.forward, dnsclass, name); - } - - public void addForwardHost(InetAddress host) { - this.forwarders.add(host); - } - - @Override - public - Response find(Name qname, int recordType) { - // TODO Auto-generated method stub - return null; - } -} diff --git a/src/dorkbox/network/dns/zone/MasterZone.java b/src/dorkbox/network/dns/zone/MasterZone.java deleted file mode 100644 index 2309aacd..00000000 --- a/src/dorkbox/network/dns/zone/MasterZone.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.zone; - -import java.util.HashSet; -import java.util.NavigableSet; -import java.util.Set; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ConcurrentSkipListMap; -import java.util.concurrent.ConcurrentSkipListSet; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.records.DnsRecord; -import dorkbox.network.dns.records.SOARecord; -import dorkbox.network.dns.server.CNAMEResponse; -import dorkbox.network.dns.server.DNAMEResponse; -import dorkbox.network.dns.server.NoErrorResponse; -import dorkbox.network.dns.server.NotFoundResponse; -import dorkbox.network.dns.server.ReferralResponse; -import dorkbox.network.dns.server.Response; - -public -class MasterZone extends AbstractZone { - - final ConcurrentMap>> records = new ConcurrentSkipListMap>>(); - - final Response nxDomain; - final Response nxRRSet; - - public - MasterZone(Name name, SOARecord soaRecord) { - super(ZoneType.master, name); - - this.nxDomain = new NotFoundResponse(DnsResponseCode.NXDOMAIN, soaRecord); - this.nxRRSet = new NotFoundResponse(DnsResponseCode.NXRRSET, soaRecord); - } - - // add and remove needs queuing? - // if modify operations works on single thread, not conflict. - public synchronized - void add(DnsRecord rr) { - - for (; ; ) { - ConcurrentMap> current = this.records.get(rr.getName()); - if (current == null) { - ConcurrentMap> newone = new ConcurrentSkipListMap>(); - NavigableSet newset = new ConcurrentSkipListSet(); - newset.add(rr); - newone.put(rr.getType(), newset); - - ConcurrentMap> prevTypes = this.records.putIfAbsent(rr.getName(), newone); - if (prevTypes == null) { - break; - } - synchronized (prevTypes) { - Set prevRecs = prevTypes.putIfAbsent(rr.getType(), newset); - if (prevRecs == null) { - break; - } - prevRecs.add(rr); - break; - } - } - else { - synchronized (current) { - Set rrs = current.get(rr.getType()); - if (rrs == null) { - NavigableSet newset = new ConcurrentSkipListSet(); - newset.add(rr); - current.put(rr.getType(), newset); - break; - } - if (!rrs.isEmpty()) { - rrs.add(rr); - break; - } - } - } - } - } - - @Override - public - Response find(Name queryName, int recordType) { - if (!queryName.equals(this.name)) { - return this.nxDomain; - } - - ConcurrentMap> exactMatch = this.records.get(queryName); - - if (exactMatch != null) { - NavigableSet rrs = exactMatch.get(recordType); - - if (rrs != null) { - synchronized (rrs) { - if (rrs.isEmpty()) { - return new NoErrorResponse(rrs); - } - } - } - - if (DnsRecordType.ANY == recordType) { - Set newset = new HashSet(); - for (Integer type : exactMatch.keySet()) { - Set s = exactMatch.get(type); - if (s != null) { - synchronized (s) { - newset.addAll(s); - } - } - } - - if (newset.isEmpty()) { - return null; - } - } - - if (DnsRecordType.CNAME == recordType) { - rrs = exactMatch.get(DnsRecordType.CNAME); - - if (rrs != null) { - synchronized (rrs) { - if (!rrs.isEmpty()) { - return new CNAMEResponse(rrs.first(), recordType); - } - } - } - } - - return this.nxRRSet; - } - - for (Name qn = queryName.parent(1); !this.name() - .equals(qn); qn = qn.parent(1)) { - ConcurrentMap> match = this.records.get(qn); - - if (match != null) { - synchronized (match) { - if (!match.isEmpty()) { - NavigableSet set = match.get(DnsRecordType.NS); - if ((set != null) && (!set.isEmpty())) { - return new ReferralResponse(set); - } - - set = match.get(DnsRecordType.DNAME); - if ((set != null) && (!set.isEmpty())) { - return new DNAMEResponse(set.first(), queryName, recordType); - } - } - } - } - } - - for (Name qn = queryName; !this.name() - .equals(qn); qn = qn.parent(1)) { - Name wild = qn.wild(1); - - ConcurrentMap> match = this.records.get(wild); - if (match != null) { - synchronized (match) { - if (!match.isEmpty()) { - Set matchSet = match.get(recordType); - - if (!matchSet.isEmpty()) { - Set set = new HashSet(matchSet.size()); - for (DnsRecord rr : matchSet) { - set.add(DnsRecord.newRecord(queryName, rr.getType(), rr.getDClass(), rr.getTTL())); - } - - return new NoErrorResponse(set); - } - } - } - } - } - - return this.nxDomain; - } - - public synchronized - void remove(DnsRecord rr, boolean checkSets, boolean checkMap) { - ConcurrentMap> current = this.records.get(rr.getName()); - if (current != null) { - synchronized (current) { - NavigableSet sets = current.get(rr.getType()); - sets.remove(rr); - if (checkSets && sets.isEmpty()) { - current.remove(rr.getType()); - if (checkMap && current.isEmpty()) { - this.records.remove(rr.getName()); - } - } - } - } - } -} diff --git a/src/dorkbox/network/dns/zone/Query.java b/src/dorkbox/network/dns/zone/Query.java deleted file mode 100644 index 45cee24a..00000000 --- a/src/dorkbox/network/dns/zone/Query.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.zone; - - -import java.util.List; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.records.DnsRecord; - -/** - * @author taichi - */ -public -class Query { - - protected Name origin; - protected Name current; - - protected int dnsClass; - - protected Zone target; - - protected ZoneDatabase database; - - public - Query(Name origin, Name current, int dnsClass, Zone target, ZoneDatabase database) { - super(); - - this.origin = origin; - this.current = current; - this.dnsClass = dnsClass; - this.target = target; - this.database = database; - } - - protected - boolean contains(List rrs) { - for (DnsRecord rr : rrs) { - if (this.origin.equals(rr.getName())) { - return true; - } - } - return false; - } -} diff --git a/src/dorkbox/network/dns/zone/SearchResult.java b/src/dorkbox/network/dns/zone/SearchResult.java deleted file mode 100644 index e72e12d0..00000000 --- a/src/dorkbox/network/dns/zone/SearchResult.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.zone; - -import java.util.List; - -import dorkbox.network.dns.records.DnsRecord; - -public class SearchResult { - - public enum Status { - NXDOMAIN, SUCCESS - } - - List rrs; - - Status status = Status.NXDOMAIN; - - public SearchResult(List rrs) { - super(); - this.rrs = rrs; - } -} diff --git a/src/dorkbox/network/dns/zone/Zone.java b/src/dorkbox/network/dns/zone/Zone.java deleted file mode 100644 index c9750ac4..00000000 --- a/src/dorkbox/network/dns/zone/Zone.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.zone; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.server.Response; - -public -interface Zone { - int dnsClass(); - - Response find(Name qname, int recordType); - - Name name(); - - ZoneType type(); -} diff --git a/src/dorkbox/network/dns/zone/ZoneDatabase.java b/src/dorkbox/network/dns/zone/ZoneDatabase.java deleted file mode 100644 index dc1bfbc6..00000000 --- a/src/dorkbox/network/dns/zone/ZoneDatabase.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.zone; - -import java.util.Map; -import java.util.concurrent.ConcurrentSkipListMap; - -import dorkbox.network.dns.Name; - -public -class ZoneDatabase { - - protected Map zones = new ConcurrentSkipListMap(); - - public - void add(Zone zone/* TODO ZoneConfig? */) { - this.zones.put(new ZoneDatabaseKey(zone), zone); - } - - public - Query prepare(Name name, int dnsClass) { - ZoneDatabaseKey zk = new ZoneDatabaseKey(name, dnsClass); - Zone found = this.zones.get(zk); - if (found != null) { - // exact match - return new Query(name, name, dnsClass, found, this); - } - - Name child = name; - // partial match - for (int i = 0, size = this.zones.size(); i < size; i++) { - Name p = child.parent(1); - zk.name(p); - found = this.zones.get(zk); - if (found == null) { - if (p.labels() <= 1) { - break; - } - - child = p; - } - else { - return new Query(name, p, dnsClass, found, this); - } - } - - // not found. - return null; - } -} diff --git a/src/dorkbox/network/dns/zone/ZoneDatabaseKey.java b/src/dorkbox/network/dns/zone/ZoneDatabaseKey.java deleted file mode 100644 index 0622b57a..00000000 --- a/src/dorkbox/network/dns/zone/ZoneDatabaseKey.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.zone; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.records.DnsRecord; - -/** - * - */ -class ZoneDatabaseKey implements Comparable { - Name name; - int dnsclass; - - public - ZoneDatabaseKey(Zone z) { - this(z.name(), z.dnsClass()); - } - - public - ZoneDatabaseKey(DnsRecord rr) { - this(rr.getName(), rr.getDClass()); - } - - public - ZoneDatabaseKey(Name name, int dnsclass) { - this.name = name; - this.dnsclass = dnsclass; - } - - @Override - public - int compareTo(ZoneDatabaseKey o) { - if (o == null) { - return 1; - } - if (equals(o)) { - return 0; - } - return this.hashCode() - o.hashCode(); - } - - public - boolean equals(ZoneDatabaseKey other) { - return (this.dnsclass == other.dnsclass) && this.name.equals(other.name); - } - - @Override - public - boolean equals(Object other) { - if (this == other) { - return true; - } - if (other == null) { - return false; - } - if (getClass() != other.getClass()) { - return false; - } - return equals((ZoneDatabaseKey) other); - } - - @Override - public - int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + this.dnsclass; - result = prime * result + this.name.hashCode(); - return result; - } - - public - Name name() { - return this.name; - } - - public - void name(Name name) { - this.name = name; - } -} diff --git a/src/dorkbox/network/dns/zone/ZoneType.java b/src/dorkbox/network/dns/zone/ZoneType.java deleted file mode 100644 index 3bc7f60f..00000000 --- a/src/dorkbox/network/dns/zone/ZoneType.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns.zone; - -public -enum ZoneType { - master, slave, stub, forward, rootHint -} diff --git a/test/dorkbox/network/dns/AddressTest.java b/test/dorkbox/network/dns/AddressTest.java deleted file mode 100644 index 3fdd94ff..00000000 --- a/test/dorkbox/network/dns/AddressTest.java +++ /dev/null @@ -1,339 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; - -import dorkbox.network.dns.utils.Address; -import junit.framework.TestCase; - -public -class AddressTest extends TestCase { - public - void test_toByteArray_invalid() { - try { - Address.toByteArray("doesn't matter", 3); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_toByteArray_IPv4() { - byte[] exp = new byte[] {(byte) 198, (byte) 121, (byte) 10, (byte) 234}; - byte[] ret = Address.toByteArray("198.121.10.234", Address.IPv4); - assertEquals(exp, ret); - - exp = new byte[] {0, 0, 0, 0}; - ret = Address.toByteArray("0.0.0.0", Address.IPv4); - assertEquals(exp, ret); - - exp = new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; - ret = Address.toByteArray("255.255.255.255", Address.IPv4); - } - - private - void assertEquals(byte[] exp, byte[] act) { - assertTrue(Arrays.equals(exp, act)); - } - - public - void test_toByteArray_IPv4_invalid() { - assertNull(Address.toByteArray("A.B.C.D", Address.IPv4)); - - assertNull(Address.toByteArray("128...", Address.IPv4)); - assertNull(Address.toByteArray("128.121", Address.IPv4)); - assertNull(Address.toByteArray("128.111.8", Address.IPv4)); - assertNull(Address.toByteArray("128.198.10.", Address.IPv4)); - - assertNull(Address.toByteArray("128.121.90..10", Address.IPv4)); - assertNull(Address.toByteArray("128.121..90.10", Address.IPv4)); - assertNull(Address.toByteArray("128..121.90.10", Address.IPv4)); - assertNull(Address.toByteArray(".128.121.90.10", Address.IPv4)); - - assertNull(Address.toByteArray("128.121.90.256", Address.IPv4)); - assertNull(Address.toByteArray("128.121.256.10", Address.IPv4)); - assertNull(Address.toByteArray("128.256.90.10", Address.IPv4)); - assertNull(Address.toByteArray("256.121.90.10", Address.IPv4)); - - assertNull(Address.toByteArray("128.121.90.-1", Address.IPv4)); - assertNull(Address.toByteArray("128.121.-1.10", Address.IPv4)); - assertNull(Address.toByteArray("128.-1.90.10", Address.IPv4)); - assertNull(Address.toByteArray("-1.121.90.10", Address.IPv4)); - - assertNull(Address.toByteArray("120.121.90.10.10", Address.IPv4)); - - assertNull(Address.toByteArray("120.121.90.010", Address.IPv4)); - assertNull(Address.toByteArray("120.121.090.10", Address.IPv4)); - assertNull(Address.toByteArray("120.021.90.10", Address.IPv4)); - assertNull(Address.toByteArray("020.121.90.10", Address.IPv4)); - - assertNull(Address.toByteArray("1120.121.90.10", Address.IPv4)); - assertNull(Address.toByteArray("120.2121.90.10", Address.IPv4)); - assertNull(Address.toByteArray("120.121.4190.10", Address.IPv4)); - assertNull(Address.toByteArray("120.121.190.1000", Address.IPv4)); - - assertNull(Address.toByteArray("", Address.IPv4)); - } - - public - void test_toByteArray_IPv6() { - byte[] exp = new byte[] {(byte) 32, (byte) 1, (byte) 13, (byte) 184, (byte) 133, (byte) 163, (byte) 8, (byte) 211, (byte) 19, - (byte) 25, (byte) 138, (byte) 46, (byte) 3, (byte) 112, (byte) 115, (byte) 52}; - byte[] ret = Address.toByteArray("2001:0db8:85a3:08d3:1319:8a2e:0370:7334", Address.IPv6); - assertEquals(exp, ret); - ret = Address.toByteArray("2001:db8:85a3:8d3:1319:8a2e:370:7334", Address.IPv6); - assertEquals(exp, ret); - ret = Address.toByteArray("2001:DB8:85A3:8D3:1319:8A2E:370:7334", Address.IPv6); - assertEquals(exp, ret); - - exp = new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - ret = Address.toByteArray("0:0:0:0:0:0:0:0", Address.IPv6); - assertEquals(exp, ret); - - exp = new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, - (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; - ret = Address.toByteArray("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", Address.IPv6); - assertEquals(exp, ret); - - exp = new byte[] {(byte) 32, (byte) 1, (byte) 13, (byte) 184, (byte) 0, (byte) 0, (byte) 8, (byte) 211, (byte) 19, (byte) 25, - (byte) 138, (byte) 46, (byte) 3, (byte) 112, (byte) 115, (byte) 52}; - ret = Address.toByteArray("2001:0db8:0000:08d3:1319:8a2e:0370:7334", Address.IPv6); - assertEquals(exp, ret); - - ret = Address.toByteArray("2001:0db8::08d3:1319:8a2e:0370:7334", Address.IPv6); - assertEquals(exp, ret); - - exp = new byte[] {(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 133, (byte) 163, (byte) 8, (byte) 211, (byte) 19, (byte) 25, - (byte) 138, (byte) 46, (byte) 3, (byte) 112, (byte) 115, (byte) 52}; - ret = Address.toByteArray("0000:0000:85a3:08d3:1319:8a2e:0370:7334", Address.IPv6); - assertEquals(exp, ret); - ret = Address.toByteArray("::85a3:08d3:1319:8a2e:0370:7334", Address.IPv6); - assertEquals(exp, ret); - - exp = new byte[] {(byte) 32, (byte) 1, (byte) 13, (byte) 184, (byte) 133, (byte) 163, (byte) 8, (byte) 211, (byte) 19, (byte) 25, - (byte) 138, (byte) 46, (byte) 0, (byte) 0, (byte) 0, (byte) 0}; - ret = Address.toByteArray("2001:0db8:85a3:08d3:1319:8a2e:0:0", Address.IPv6); - assertEquals(exp, ret); - - ret = Address.toByteArray("2001:0db8:85a3:08d3:1319:8a2e::", Address.IPv6); - assertEquals(exp, ret); - - exp = new byte[] {(byte) 32, (byte) 1, (byte) 13, (byte) 184, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, - (byte) 0, (byte) 3, (byte) 112, (byte) 115, (byte) 52}; - ret = Address.toByteArray("2001:0db8:0000:0000:0000:0000:0370:7334", Address.IPv6); - assertEquals(exp, ret); - ret = Address.toByteArray("2001:0db8:0:0:0:0:0370:7334", Address.IPv6); - assertEquals(exp, ret); - ret = Address.toByteArray("2001:0db8::0:0370:7334", Address.IPv6); - assertEquals(exp, ret); - ret = Address.toByteArray("2001:db8::370:7334", Address.IPv6); - assertEquals(exp, ret); - - exp = new byte[] {(byte) 32, (byte) 1, (byte) 13, (byte) 184, (byte) 133, (byte) 163, (byte) 8, (byte) 211, (byte) 19, (byte) 25, - (byte) 138, (byte) 46, (byte) 0xC0, (byte) 0xA8, (byte) 0x59, (byte) 0x09}; - ret = Address.toByteArray("2001:0db8:85a3:08d3:1319:8a2e:192.168.89.9", Address.IPv6); - assertEquals(exp, ret); - - exp = new byte[] {(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, - (byte) 0, (byte) 0xC0, (byte) 0xA8, (byte) 0x59, (byte) 0x09}; - ret = Address.toByteArray("::192.168.89.9", Address.IPv6); - assertEquals(exp, ret); - } - - public - void test_toByteArray_IPv6_invalid() { - // not enough groups - assertNull(Address.toByteArray("2001:0db8:85a3:08d3:1319:8a2e:0370", Address.IPv6)); - // too many groups - assertNull(Address.toByteArray("2001:0db8:85a3:08d3:1319:8a2e:0370:193A:BCdE", Address.IPv6)); - // invalid letter - assertNull(Address.toByteArray("2001:0gb8:85a3:08d3:1319:8a2e:0370:9819", Address.IPv6)); - assertNull(Address.toByteArray("lmno:0bb8:85a3:08d3:1319:8a2e:0370:9819", Address.IPv6)); - assertNull(Address.toByteArray("11ab:0ab8:85a3:08d3:1319:8a2e:0370:qrst", Address.IPv6)); - // three consecutive colons - assertNull(Address.toByteArray("11ab:0ab8:85a3:08d3:::", Address.IPv6)); - // IPv4 in the middle - assertNull(Address.toByteArray("2001:0ab8:192.168.0.1:1319:8a2e:0370:9819", Address.IPv6)); - // invalid IPv4 - assertNull(Address.toByteArray("2001:0ab8:1212:AbAb:8a2e:345.12.22.1", Address.IPv6)); - // group with too many digits - assertNull(Address.toByteArray("2001:0ab8:85a3:128d3:1319:8a2e:0370:9819", Address.IPv6)); - - } - - public - void test_toArray() { - int[] exp = new int[] {1, 2, 3, 4}; - int[] ret = Address.toArray("1.2.3.4", Address.IPv4); - assertEquals(exp, ret); - - exp = new int[] {0, 0, 0, 0}; - ret = Address.toArray("0.0.0.0", Address.IPv4); - assertEquals(exp, ret); - - exp = new int[] {255, 255, 255, 255}; - ret = Address.toArray("255.255.255.255", Address.IPv4); - assertEquals(exp, ret); - } - - private - void assertEquals(int[] exp, int[] act) { - assertEquals(exp.length, act.length); - for (int i = 0; i < exp.length; ++i) { - assertEquals("i=" + i, exp[i], act[i]); - } - } - - public - void test_toArray_invalid() { - assertNull(Address.toArray("128.121.1", Address.IPv4)); - - assertNull(Address.toArray("")); - } - - public - void test_isDottedQuad() { - assertTrue(Address.isDottedQuad("1.2.3.4")); - assertFalse(Address.isDottedQuad("256.2.3.4")); - } - - public - void test_toDottedQuad() { - assertEquals("128.176.201.1", Address.toDottedQuad(new byte[] {(byte) 128, (byte) 176, (byte) 201, (byte) 1})); - - assertEquals("200.1.255.128", Address.toDottedQuad(new int[] {200, 1, 255, 128})); - } - - public - void test_addressLength() { - assertEquals(4, Address.addressLength(Address.IPv4)); - assertEquals(16, Address.addressLength(Address.IPv6)); - - try { - Address.addressLength(3); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_getByName() throws UnknownHostException { - InetAddress out = Address.getByName("128.145.198.231"); - assertEquals("128.145.198.231", out.getHostAddress()); - - out = Address.getByName("a.root-servers.net"); - assertEquals("198.41.0.4", out.getHostAddress()); - } - - public - void test_getByName_invalid() throws UnknownHostException { - try { - Address.getByName("example.invalid"); - fail("UnknownHostException not thrown"); - } catch (UnknownHostException ignored) { - } - - try { - InetAddress byName = Address.getByName(""); - assertEquals("127.0.0.1", byName.getHostAddress()); - } catch (UnknownHostException ignored) { - fail("UnknownHostException thrown"); - } - } - - public - void test_getAllByName() throws UnknownHostException { - InetAddress[] out = Address.getAllByName("128.145.198.231"); - assertEquals(1, out.length); - assertEquals("128.145.198.231", out[0].getHostAddress()); - - out = Address.getAllByName("a.root-servers.net"); - assertTrue(out.length == 2); - assertEquals("198.41.0.4", out[0].getHostAddress()); - assertEquals("2001:503:ba3e:0:0:0:2:30", out[1].getHostAddress()); - - out = Address.getAllByName("cnn.com"); - assertTrue(out.length > 1); - for (int i = 0; i < out.length; ++i) { - String hostName = out[i].getHostName(); - assertTrue(hostName.endsWith("cnn.com")); - } - } - - public - void test_getAllByName_invalid() throws UnknownHostException { - try { - Address.getAllByName("example.invalid"); - fail("UnknownHostException not thrown"); - } catch (UnknownHostException ignored) { - } - - try { - InetAddress[] byName = Address.getAllByName(""); - assertEquals("127.0.0.1", byName[0].getHostAddress()); - assertEquals("0:0:0:0:0:0:0:1", byName[1].getHostAddress()); - } catch (UnknownHostException ignored) { - fail("UnknownHostException thrown"); - } - } - - public - void test_familyOf() throws UnknownHostException { - assertEquals(Address.IPv4, Address.familyOf(InetAddress.getByName("192.168.0.1"))); - assertEquals(Address.IPv6, Address.familyOf(InetAddress.getByName("1:2:3:4:5:6:7:8"))); - - try { - Address.familyOf(null); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_getHostName() throws UnknownHostException { - InetAddress byName = InetAddress.getByName("198.41.0.4"); - String out = Address.getHostName(byName); - assertEquals("a.root-servers.net.", out); - - try { - Address.getHostName(InetAddress.getByName("192.168.1.1")); - fail("UnknownHostException not thrown"); - } catch (UnknownHostException ignored) { - } - } -} diff --git a/test/dorkbox/network/dns/CompressionTest.java b/test/dorkbox/network/dns/CompressionTest.java deleted file mode 100644 index 95b378a8..00000000 --- a/test/dorkbox/network/dns/CompressionTest.java +++ /dev/null @@ -1,62 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Options; -import junit.framework.TestCase; - -public -class CompressionTest extends TestCase { - @Override - public - void setUp() { - Options.set("verbosecompression"); - } - - public - void test() throws TextParseException { - Compression c = new Compression(); - Name n = Name.fromString("www.amazon.com."); - - c.add(10, n); - assertEquals(10, c.get(n)); - - Name n2 = Name.fromString("www.cnn.com."); - - c.add(10, n2); - assertEquals(10, c.get(n2)); - } -} diff --git a/test/dorkbox/network/dns/DClassTest.java b/test/dorkbox/network/dns/DClassTest.java deleted file mode 100644 index cd4958e5..00000000 --- a/test/dorkbox/network/dns/DClassTest.java +++ /dev/null @@ -1,86 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import dorkbox.network.dns.constants.DnsClass; -import junit.framework.TestCase; - -public -class DClassTest extends TestCase { - public - void test_string() { - // a regular one - assertEquals("IN", DnsClass.string(DnsClass.IN)); - - // one with an alias - assertEquals("CH", DnsClass.string(DnsClass.CH)); - - // one that doesn't exist - assertTrue(DnsClass.string(20) - .startsWith("CLASS")); - - try { - DnsClass.string(-1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - - // (max is 0xFFFF) - try { - DnsClass.string(0x10000); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_value() { - // regular one - assertEquals(DnsClass.NONE, DnsClass.value("NONE")); - - // one with alias - assertEquals(DnsClass.HS, DnsClass.value("HS")); - assertEquals(DnsClass.HS, DnsClass.value("HESIOD")); - - // one thats undefined but within range - assertEquals(21, DnsClass.value("CLASS21")); - - // something that unknown - assertEquals(-1, DnsClass.value("THIS IS DEFINITELY UNKNOWN")); - - // empty string - assertEquals(-1, DnsClass.value("")); - } -} diff --git a/test/dorkbox/network/dns/DNSInputTest.java b/test/dorkbox/network/dns/DNSInputTest.java deleted file mode 100644 index 8274db6a..00000000 --- a/test/dorkbox/network/dns/DNSInputTest.java +++ /dev/null @@ -1,306 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import java.util.Arrays; - -import dorkbox.network.dns.exceptions.WireParseException; -import junit.framework.TestCase; - -public -class DNSInputTest extends TestCase { - private byte[] m_raw; - private DnsInput m_di; - - @Override - public - void setUp() { - m_raw = new byte[] {0, 1, 2, 3, 4, 5, (byte) 255, (byte) 255, (byte) 255, (byte) 255}; - m_di = new DnsInput(m_raw); - } - - public - void test_initial_state() { - assertEquals(0, m_di.readIndex()); - assertEquals(10, m_di.remaining()); - } - - public - void test_jump1() { - m_di.jump(1); - assertEquals(1, m_di.readIndex()); - assertEquals(9, m_di.remaining()); - } - - public - void test_jump2() { - m_di.jump(9); - assertEquals(9, m_di.readIndex()); - assertEquals(1, m_di.remaining()); - } - - public - void test_jump_invalid() { - try { - m_di.jump(10); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - // pass - } - } - - public - void test_setActive() { - m_di.setActive(5); - assertEquals(0, m_di.readIndex()); - assertEquals(5, m_di.remaining()); - } - - public - void test_setActive_boundary1() { - m_di.setActive(10); - assertEquals(0, m_di.readIndex()); - assertEquals(10, m_di.remaining()); - } - - public - void test_setActive_boundary2() { - m_di.setActive(0); - assertEquals(0, m_di.readIndex()); - assertEquals(0, m_di.remaining()); - } - - public - void test_setActive_invalid() { - try { - m_di.setActive(11); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - // pass - } - } - - public - void test_clearActive() { - // first without setting active: - m_di.restoreActive(); - assertEquals(0, m_di.readIndex()); - assertEquals(10, m_di.remaining()); - - m_di.setActive(5); - m_di.restoreActive(); - assertEquals(0, m_di.readIndex()); - assertEquals(10, m_di.remaining()); - } - - public - void test_restore_invalid() { - try { - m_di.restore(); - fail("IllegalStateException not thrown"); - } catch (IllegalStateException e) { - // pass - } - } - - public - void test_save_restore() { - m_di.jump(4); - assertEquals(4, m_di.readIndex()); - assertEquals(6, m_di.remaining()); - - m_di.save(); - m_di.jump(0); - assertEquals(0, m_di.readIndex()); - assertEquals(10, m_di.remaining()); - - m_di.restore(); - assertEquals(4, m_di.readIndex()); - assertEquals(6, m_di.remaining()); - } - - public - void test_readU8_basic() throws WireParseException { - int v1 = m_di.readU8(); - assertEquals(1, m_di.readIndex()); - assertEquals(9, m_di.remaining()); - assertEquals(0, v1); - } - - public - void test_readU8_maxval() throws WireParseException { - m_di.jump(9); - int v1 = m_di.readU8(); - assertEquals(10, m_di.readIndex()); - assertEquals(0, m_di.remaining()); - assertEquals(255, v1); - - try { - v1 = m_di.readU8(); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - // pass - } - } - - public - void test_readU16_basic() throws WireParseException { - int v1 = m_di.readU16(); - assertEquals(2, m_di.readIndex()); - assertEquals(8, m_di.remaining()); - assertEquals(1, v1); - - m_di.jump(1); - v1 = m_di.readU16(); - assertEquals(258, v1); - } - - public - void test_readU16_maxval() throws WireParseException { - m_di.jump(8); - int v = m_di.readU16(); - assertEquals(10, m_di.readIndex()); - assertEquals(0, m_di.remaining()); - assertEquals(0xFFFF, v); - - try { - m_di.jump(9); - m_di.readU16(); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - // pass - } - } - - public - void test_readU32_basic() throws WireParseException { - long v1 = m_di.readU32(); - assertEquals(4, m_di.readIndex()); - assertEquals(6, m_di.remaining()); - assertEquals(66051, v1); - } - - public - void test_readU32_maxval() throws WireParseException { - m_di.jump(6); - long v = m_di.readU32(); - assertEquals(10, m_di.readIndex()); - assertEquals(0, m_di.remaining()); - assertEquals(0xFFFFFFFFL, v); - - try { - m_di.jump(7); - m_di.readU32(); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - // pass - } - } - - public - void test_readByteArray_0arg() throws WireParseException { - m_di.jump(1); - byte[] out = m_di.readByteArray(); - assertEquals(10, m_di.readIndex()); - assertEquals(0, m_di.remaining()); - assertEquals(9, out.length); - for (int i = 0; i < 9; ++i) { - assertEquals(m_raw[i + 1], out[i]); - } - } - - public - void test_readByteArray_0arg_boundary() throws WireParseException { - m_di.jump(9); - m_di.readU8(); - byte[] out = m_di.readByteArray(); - assertEquals(0, out.length); - } - - public - void test_readByteArray_1arg() throws WireParseException { - byte[] out = m_di.readByteArray(2); - assertEquals(2, m_di.readIndex()); - assertEquals(8, m_di.remaining()); - assertEquals(2, out.length); - assertEquals(0, out[0]); - assertEquals(1, out[1]); - } - - public - void test_readByteArray_1arg_boundary() throws WireParseException { - byte[] out = m_di.readByteArray(10); - assertEquals(10, m_di.readIndex()); - assertEquals(0, m_di.remaining()); - assertEquals(m_raw, out); - } - - private - void assertEquals(byte[] exp, byte[] act) { - assertTrue(Arrays.equals(exp, act)); - } - - public - void test_readByteArray_1arg_invalid() { - try { - m_di.readByteArray(11); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - // pass - } - } - - public - void test_readByteArray_3arg() throws WireParseException { - byte[] data = new byte[5]; - m_di.jump(4); - - m_di.readByteArray(data, 1, 4); - assertEquals(8, m_di.readIndex()); - assertEquals(0, data[0]); - for (int i = 0; i < 4; ++i) { - assertEquals(m_raw[i + 4], data[i + 1]); - } - } - - public - void test_readCountedSting() throws WireParseException { - m_di.jump(1); - byte[] out = m_di.readCountedString(); - assertEquals(1, out.length); - assertEquals(3, m_di.readIndex()); - assertEquals(out[0], 2); - } -} diff --git a/test/dorkbox/network/dns/ExceptionTest.java b/test/dorkbox/network/dns/ExceptionTest.java deleted file mode 100644 index 176f3bcb..00000000 --- a/test/dorkbox/network/dns/ExceptionTest.java +++ /dev/null @@ -1,113 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import java.io.IOException; - -import dorkbox.network.dns.exceptions.InvalidDClassException; -import dorkbox.network.dns.exceptions.InvalidTTLException; -import dorkbox.network.dns.exceptions.InvalidTypeException; -import dorkbox.network.dns.exceptions.NameTooLongException; -import dorkbox.network.dns.exceptions.RelativeNameException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.network.dns.exceptions.ZoneTransferException; -import junit.framework.TestCase; - -public -class ExceptionTest extends TestCase { - public - void test_InvalidDClassException() { - IllegalArgumentException e = new InvalidDClassException(10); - assertEquals("Invalid DNS class: 10", e.getMessage()); - } - - public - void test_InvalidTTLException() { - IllegalArgumentException e = new InvalidTTLException(32345); - assertEquals("Invalid DNS TTL: 32345", e.getMessage()); - } - - public - void test_InvalidTypeException() { - IllegalArgumentException e = new InvalidTypeException(32345); - assertEquals("Invalid DNS type: 32345", e.getMessage()); - } - - public - void test_NameTooLongException() { - WireParseException e = new NameTooLongException(); - assertNull(e.getMessage()); - - e = new NameTooLongException("This is my too long name"); - assertEquals("This is my too long name", e.getMessage()); - } - - public - void test_RelativeNameException() throws TextParseException { - IllegalArgumentException e = new RelativeNameException("This is my relative name"); - assertEquals("This is my relative name", e.getMessage()); - - e = new RelativeNameException(Name.fromString("relative")); - assertEquals("'relative' is not an absolute name", e.getMessage()); - } - - public - void test_TextParseException() { - IOException e = new TextParseException(); - assertNull(e.getMessage()); - - e = new TextParseException("This is my message"); - assertEquals("This is my message", e.getMessage()); - } - - public - void test_WireParseException() { - IOException e = new WireParseException(); - assertNull(e.getMessage()); - - e = new WireParseException("This is my message"); - assertEquals("This is my message", e.getMessage()); - } - - public - void test_ZoneTransferException() { - Exception e = new ZoneTransferException(); - assertNull(e.getMessage()); - - e = new ZoneTransferException("This is my message"); - assertEquals("This is my message", e.getMessage()); - } -} diff --git a/test/dorkbox/network/dns/ExtendedFlagsTest.java b/test/dorkbox/network/dns/ExtendedFlagsTest.java deleted file mode 100644 index c9e741fe..00000000 --- a/test/dorkbox/network/dns/ExtendedFlagsTest.java +++ /dev/null @@ -1,82 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import dorkbox.network.dns.constants.ExtendedFlags; -import junit.framework.TestCase; - -public -class ExtendedFlagsTest extends TestCase { - public - void test_string() { - // a regular one - assertEquals("do", ExtendedFlags.DO.string()); - - // one that doesn't exist - assertTrue(ExtendedFlags.string(1) - .startsWith("flag")); - - try { - ExtendedFlags.string(-1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - - // (max is 0xFFFF) - try { - ExtendedFlags.string(0x10000); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_value() { - // regular one - assertEquals(ExtendedFlags.DO.value(), ExtendedFlags.value("do")); - - // one thats undefined but within range - assertEquals(16, ExtendedFlags.value("FLAG16")); - - // one thats undefined but out of range - assertEquals(-1, ExtendedFlags.value("FLAG" + 0x10000)); - - // something that unknown - assertEquals(-1, ExtendedFlags.value("THIS IS DEFINITELY UNKNOWN")); - - // empty string - assertEquals(-1, ExtendedFlags.value("")); - } -} diff --git a/test/dorkbox/network/dns/FlagsTest.java b/test/dorkbox/network/dns/FlagsTest.java deleted file mode 100644 index 0a0c499d..00000000 --- a/test/dorkbox/network/dns/FlagsTest.java +++ /dev/null @@ -1,125 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import dorkbox.network.dns.constants.Flags; -import junit.framework.TestCase; - -public -class FlagsTest extends TestCase { - public - void test_string() { - // a regular one - assertEquals("aa", Flags.AA.string()); - - // one that doesn't exist - try { - Flags.toFlag(12); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - - try { - Flags.toFlag(-1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - - // (max is 0xF) - try { - Flags.toFlag(0x10); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_value() { - // regular one - assertEquals(Flags.CD, Flags.toFlag("cd")); - - // one that's undefined but within range - try { - Flags.toFlag("FLAG13"); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - - // one that's undefined but out of range - try { - Flags.toFlag("FLAG" + 0x10); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - - // something that's unknown - try { - Flags.toFlag("THIS IS DEFINITELY UNKNOWN"); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - - // empty string - try { - Flags.toFlag(""); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_isFlag() { - assertFalse(Flags.isFlag(-1)); // invalid - - assertTrue(Flags.isFlag(0)); - assertFalse(Flags.isFlag(1)); // opcode - assertFalse(Flags.isFlag(2)); - assertFalse(Flags.isFlag(3)); - assertFalse(Flags.isFlag(4)); - assertTrue(Flags.isFlag(5)); - assertTrue(Flags.isFlag(6)); - assertTrue(Flags.isFlag(7)); - assertTrue(Flags.isFlag(8)); - assertTrue(Flags.isFlag(9)); - assertTrue(Flags.isFlag(10)); - assertTrue(Flags.isFlag(11)); - assertFalse(Flags.isFlag(12)); - assertFalse(Flags.isFlag(13)); - assertFalse(Flags.isFlag(14)); - assertFalse(Flags.isFlag(15)); - - assertFalse(Flags.isFlag(16)); // invalid - } -} diff --git a/test/dorkbox/network/dns/FormattedTimeTest.java b/test/dorkbox/network/dns/FormattedTimeTest.java deleted file mode 100644 index 7a8bc2fb..00000000 --- a/test/dorkbox/network/dns/FormattedTimeTest.java +++ /dev/null @@ -1,90 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.TimeZone; - -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.FormattedTime; -import junit.framework.TestCase; - -public -class FormattedTimeTest extends TestCase { - public - void test_format() { - GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - cal.set(2005, 2, 19, 4, 4, 5); - String out = FormattedTime.format(cal.getTime()); - assertEquals("20050319040405", out); - } - - public - void test_parse() throws TextParseException { - // have to make sure to clear out the milliseconds since there - // is occasionally a difference between when cal and cal2 are - // instantiated. - GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - cal.set(2005, 2, 19, 4, 4, 5); - cal.set(Calendar.MILLISECOND, 0); - - Date out = FormattedTime.parse("20050319040405"); - GregorianCalendar cal2 = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - cal2.setTimeInMillis(out.getTime()); - cal2.set(Calendar.MILLISECOND, 0); - assertEquals(cal, cal2); - } - - public - void test_parse_invalid() { - try { - FormattedTime.parse("2004010101010"); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - try { - FormattedTime.parse("200401010101010"); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - try { - FormattedTime.parse("2004010101010A"); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } -} diff --git a/test/dorkbox/network/dns/NameTest.java b/test/dorkbox/network/dns/NameTest.java deleted file mode 100644 index a3a99fe6..00000000 --- a/test/dorkbox/network/dns/NameTest.java +++ /dev/null @@ -1,1311 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import java.io.IOException; -import java.util.Arrays; - -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.exceptions.NameTooLongException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.network.dns.records.DNAMERecord; -import dorkbox.network.dns.utils.Options; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -public -class NameTest extends TestCase { - public static - class Test_String_init extends TestCase { - private final String m_abs = "WWW.DnsJava.org."; - private Name m_abs_origin; - private final String m_rel = "WWW.DnsJava"; - private Name m_rel_origin; - - @Override - protected - void setUp() throws TextParseException { - m_abs_origin = Name.fromString("Orig."); - m_rel_origin = Name.fromString("Orig"); - } - - public - void test_ctor_empty() { - try { - new Name(""); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_ctor_at_null_origin() throws TextParseException { - Name n = new Name("@"); - assertFalse(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(0, n.labels()); - assertEquals(0, n.length()); - } - - public - void test_ctor_at_abs_origin() throws TextParseException { - Name n = new Name("@", m_abs_origin); - assertEquals(m_abs_origin, n); - } - - public - void test_ctor_at_rel_origin() throws TextParseException { - Name n = new Name("@", m_rel_origin); - assertEquals(m_rel_origin, n); - } - - public - void test_ctor_dot() throws TextParseException { - Name n = new Name("."); - assertEquals(Name.root, n); - assertNotSame(Name.root, n); - assertEquals(1, n.labels()); - assertEquals(1, n.length()); - } - - public - void test_ctor_wildcard() throws TextParseException { - Name n = new Name("*"); - assertFalse(n.isAbsolute()); - assertTrue(n.isWild()); - assertEquals(1, n.labels()); - assertEquals(2, n.length()); - assertTrue(Arrays.equals(new byte[] {1, '*'}, n.getLabel(0))); - assertEquals("*", n.getLabelString(0)); - } - - public - void test_ctor_abs() throws TextParseException { - Name n = new Name(m_abs); - assertTrue(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(4, n.labels()); - assertEquals(17, n.length()); - assertTrue(Arrays.equals(new byte[] {3, 'W', 'W', 'W'}, n.getLabel(0))); - assertEquals("WWW", n.getLabelString(0)); - assertTrue(Arrays.equals(new byte[] {7, 'D', 'n', 's', 'J', 'a', 'v', 'a'}, n.getLabel(1))); - assertEquals("DnsJava", n.getLabelString(1)); - assertTrue(Arrays.equals(new byte[] {3, 'o', 'r', 'g'}, n.getLabel(2))); - assertEquals("org", n.getLabelString(2)); - assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(3))); - assertEquals("", n.getLabelString(3)); - } - - public - void test_ctor_rel() throws TextParseException { - Name n = new Name(m_rel); - assertFalse(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(2, n.labels()); - assertEquals(12, n.length()); - assertTrue(Arrays.equals(new byte[] {3, 'W', 'W', 'W'}, n.getLabel(0))); - assertEquals("WWW", n.getLabelString(0)); - assertTrue(Arrays.equals(new byte[] {7, 'D', 'n', 's', 'J', 'a', 'v', 'a'}, n.getLabel(1))); - assertEquals("DnsJava", n.getLabelString(1)); - } - - public - void test_ctor_7label() throws TextParseException { - // 7 is the number of label positions that are cached - Name n = new Name("a.b.c.d.e.f."); - assertTrue(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(7, n.labels()); - assertEquals(13, n.length()); - assertTrue(Arrays.equals(new byte[] {1, 'a'}, n.getLabel(0))); - assertEquals("a", n.getLabelString(0)); - assertTrue(Arrays.equals(new byte[] {1, 'b'}, n.getLabel(1))); - assertEquals("b", n.getLabelString(1)); - assertTrue(Arrays.equals(new byte[] {1, 'c'}, n.getLabel(2))); - assertEquals("c", n.getLabelString(2)); - assertTrue(Arrays.equals(new byte[] {1, 'd'}, n.getLabel(3))); - assertEquals("d", n.getLabelString(3)); - assertTrue(Arrays.equals(new byte[] {1, 'e'}, n.getLabel(4))); - assertEquals("e", n.getLabelString(4)); - assertTrue(Arrays.equals(new byte[] {1, 'f'}, n.getLabel(5))); - assertEquals("f", n.getLabelString(5)); - assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(6))); - assertEquals("", n.getLabelString(6)); - } - - public - void test_ctor_8label() throws TextParseException { - // 7 is the number of label positions that are cached - Name n = new Name("a.b.c.d.e.f.g."); - assertTrue(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(8, n.labels()); - assertEquals(15, n.length()); - assertTrue(Arrays.equals(new byte[] {1, 'a'}, n.getLabel(0))); - assertEquals("a", n.getLabelString(0)); - assertTrue(Arrays.equals(new byte[] {1, 'b'}, n.getLabel(1))); - assertEquals("b", n.getLabelString(1)); - assertTrue(Arrays.equals(new byte[] {1, 'c'}, n.getLabel(2))); - assertEquals("c", n.getLabelString(2)); - assertTrue(Arrays.equals(new byte[] {1, 'd'}, n.getLabel(3))); - assertEquals("d", n.getLabelString(3)); - assertTrue(Arrays.equals(new byte[] {1, 'e'}, n.getLabel(4))); - assertEquals("e", n.getLabelString(4)); - assertTrue(Arrays.equals(new byte[] {1, 'f'}, n.getLabel(5))); - assertEquals("f", n.getLabelString(5)); - assertTrue(Arrays.equals(new byte[] {1, 'g'}, n.getLabel(6))); - assertEquals("g", n.getLabelString(6)); - assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(7))); - assertEquals("", n.getLabelString(7)); - } - - public - void test_ctor_removed_label() throws TextParseException, NameTooLongException { - String pre = "prepend"; - Name stripped = new Name(Name.fromString("sub.domain.example."), 1); - Name concat = new Name(pre, stripped); - assertEquals(Name.concatenate(Name.fromString(pre), stripped), concat); - assertEquals(Name.fromString(pre, stripped), concat); - assertEquals("prepend.domain.example.", concat.toString()); - } - - public - void test_ctor_abs_abs_origin() throws TextParseException { - Name n = new Name(m_abs, m_abs_origin); - assertTrue(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(4, n.labels()); - assertEquals(17, n.length()); - assertTrue(Arrays.equals(new byte[] {3, 'W', 'W', 'W'}, n.getLabel(0))); - assertEquals("WWW", n.getLabelString(0)); - assertTrue(Arrays.equals(new byte[] {7, 'D', 'n', 's', 'J', 'a', 'v', 'a'}, n.getLabel(1))); - assertEquals("DnsJava", n.getLabelString(1)); - assertTrue(Arrays.equals(new byte[] {3, 'o', 'r', 'g'}, n.getLabel(2))); - assertEquals("org", n.getLabelString(2)); - assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(3))); - assertEquals("", n.getLabelString(3)); - } - - public - void test_ctor_abs_rel_origin() throws TextParseException { - Name n = new Name(m_abs, m_rel_origin); - assertTrue(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(4, n.labels()); - assertEquals(17, n.length()); - assertTrue(Arrays.equals(new byte[] {3, 'W', 'W', 'W'}, n.getLabel(0))); - assertEquals("WWW", n.getLabelString(0)); - assertTrue(Arrays.equals(new byte[] {7, 'D', 'n', 's', 'J', 'a', 'v', 'a'}, n.getLabel(1))); - assertEquals("DnsJava", n.getLabelString(1)); - assertTrue(Arrays.equals(new byte[] {3, 'o', 'r', 'g'}, n.getLabel(2))); - assertEquals("org", n.getLabelString(2)); - assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(3))); - assertEquals("", n.getLabelString(3)); - } - - public - void test_ctor_rel_abs_origin() throws TextParseException { - Name n = new Name(m_rel, m_abs_origin); - assertTrue(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(4, n.labels()); - assertEquals(18, n.length()); - assertTrue(Arrays.equals(new byte[] {3, 'W', 'W', 'W'}, n.getLabel(0))); - assertEquals("WWW", n.getLabelString(0)); - assertTrue(Arrays.equals(new byte[] {7, 'D', 'n', 's', 'J', 'a', 'v', 'a'}, n.getLabel(1))); - assertEquals("DnsJava", n.getLabelString(1)); - assertTrue(Arrays.equals(new byte[] {4, 'O', 'r', 'i', 'g'}, n.getLabel(2))); - assertEquals("Orig", n.getLabelString(2)); - assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(3))); - assertEquals("", n.getLabelString(3)); - } - - public - void test_ctor_invalid_label() { - try { - new Name("junk..junk."); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_ctor_max_label() throws TextParseException { - // name with a 63 char label - Name n = new Name("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b."); - assertTrue(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(3, n.labels()); - assertEquals(67, n.length()); - assertTrue(Arrays.equals(new byte[] {63, 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'}, n.getLabel(0))); - assertEquals("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", n.getLabelString(0)); - assertTrue(Arrays.equals(new byte[] {1, 'b'}, n.getLabel(1))); - assertEquals("b", n.getLabelString(1)); - assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(2))); - assertEquals("", n.getLabelString(2)); - } - - public - void test_ctor_toobig_label() { - // name with a 64 char label - try { - new Name("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b."); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_ctor_max_length_rel() throws TextParseException { - // relative name with three 63-char labels and a 62-char label - Name n = new Name("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"); - assertFalse(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(4, n.labels()); - assertEquals(255, n.length()); - } - - public - void test_ctor_max_length_abs() throws TextParseException { - // absolute name with three 63-char labels and a 61-char label - Name n = new Name("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd."); - assertTrue(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(5, n.labels()); - assertEquals(255, n.length()); - } - - public - void test_ctor_escaped() throws TextParseException { - Name n = new Name("ab\\123cd"); - assertFalse(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(1, n.labels()); - assertEquals(6, n.length()); - assertTrue(Arrays.equals(new byte[] {5, 'a', 'b', (byte) 123, 'c', 'd'}, n.getLabel(0))); - } - - public - void test_ctor_escaped_end() throws TextParseException { - Name n = new Name("abcd\\123"); - assertFalse(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(1, n.labels()); - assertEquals(6, n.length()); - assertTrue(Arrays.equals(new byte[] {5, 'a', 'b', 'c', 'd', (byte) 123}, n.getLabel(0))); - } - - public - void test_ctor_short_escaped() throws TextParseException { - try { - new Name("ab\\12cd"); - fail("TextParseException not throw"); - } catch (TextParseException e) { - } - } - - public - void test_ctor_short_escaped_end() throws TextParseException { - try { - new Name("ab\\12"); - fail("TextParseException not throw"); - } catch (TextParseException e) { - } - } - - public - void test_ctor_empty_escaped_end() throws TextParseException { - try { - new Name("ab\\"); - fail("TextParseException not throw"); - } catch (TextParseException e) { - } - } - - public - void test_ctor_toobig_escaped() throws TextParseException { - try { - new Name("ab\\256cd"); - fail("TextParseException not throw"); - } catch (TextParseException e) { - } - } - - public - void test_ctor_toobig_escaped_end() throws TextParseException { - try { - new Name("ab\\256"); - fail("TextParseException not throw"); - } catch (TextParseException e) { - } - } - - public - void test_ctor_max_label_escaped() throws TextParseException { - // name with a 63 char label containing an escape - Name n = new Name("aaaa\\100aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b."); - assertTrue(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(3, n.labels()); - assertEquals(67, n.length()); - assertTrue(Arrays.equals(new byte[] {63, 'a', 'a', 'a', 'a', (byte) 100, 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'}, n.getLabel(0))); - assertTrue(Arrays.equals(new byte[] {1, 'b'}, n.getLabel(1))); - assertEquals("b", n.getLabelString(1)); - assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(2))); - assertEquals("", n.getLabelString(2)); - } - - public - void test_ctor_max_labels() throws TextParseException { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < 127; ++i) { - sb.append("a."); - } - Name n = new Name(sb.toString()); - assertTrue(n.isAbsolute()); - assertFalse(n.isWild()); - assertEquals(128, n.labels()); - assertEquals(255, n.length()); - for (int i = 0; i < 127; ++i) { - assertTrue(Arrays.equals(new byte[] {1, 'a'}, n.getLabel(i))); - assertEquals("a", n.getLabelString(i)); - } - assertTrue(Arrays.equals(new byte[] {0}, n.getLabel(127))); - assertEquals("", n.getLabelString(127)); - } - - public - void test_ctor_toobig_label_escaped_end() throws TextParseException { - try { - // name with a 64 char label containing an escape at the end - new Name("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\090.b."); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_ctor_toobig_label_escaped() throws TextParseException { - try { - // name with a 64 char label containing an escape at the end - new Name("aaaaaaaaaaaaaaaaaaaaaaaaaaaa\\001aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.b."); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_fromString() throws TextParseException { - Name n = new Name(m_rel, m_abs_origin); - Name n2 = Name.fromString(m_rel, m_abs_origin); - assertEquals(n, n2); - } - - public - void test_fromString_at() throws TextParseException { - Name n = Name.fromString("@", m_rel_origin); - assertSame(m_rel_origin, n); - } - - public - void test_fromString_dot() throws TextParseException { - Name n = Name.fromString("."); - assertSame(Name.root, n); - } - - public - void test_fromConstantString() throws TextParseException { - Name n = new Name(m_abs); - Name n2 = Name.fromConstantString(m_abs); - assertEquals(n, n2); - } - - public - void test_fromConstantString_invalid() { - try { - Name.fromConstantString("junk..junk"); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - } - - - public static - class Test_DNSInput_init extends TestCase { - public - void test_basic() throws IOException, TextParseException, WireParseException { - - final byte[] raw = new byte[] {3, 'W', 'w', 'w', 7, 'D', 'n', 's', 'J', 'a', 'v', 'a', 3, 'o', 'r', 'g', 0}; - Name e = Name.fromString("Www.DnsJava.org."); - - Name n = new Name(raw); - assertEquals(e, n); - } - - public - void test_incomplete() throws IOException { - try { - new Name(new byte[] {3, 'W', 'w', 'w'}); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - } - } - - public - void test_root() throws WireParseException { - final byte[] raw = new byte[] {0}; - Name n = new Name(new DnsInput(raw)); - assertEquals(Name.root, n); - } - - public - void test_invalid_length() throws IOException { - try { - new Name(new byte[] {4, 'W', 'w', 'w'}); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - } - } - - public - void test_max_label_length() throws TextParseException, WireParseException { - byte[] raw = new byte[] {63, 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', - 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', - 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', - 'b', 'b', 'b', 0}; - Name e = Name.fromString("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb."); - - Name n = new Name(new DnsInput(raw)); - assertEquals(e, n); - } - - public - void test_max_name() throws TextParseException, WireParseException { - // absolute name with three 63-char labels and a 61-char label - Name e = new Name("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd."); - byte[] raw = new byte[] {63, 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 63, 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', - 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', - 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', - 'b', 'b', 'b', 'b', 'b', 'b', 63, 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', - 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', - 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', - 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 61, 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', - 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', - 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', - 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 0}; - - Name n = new Name(new DnsInput(raw)); - assertEquals(e, n); - } - - public - void test_toolong_name() throws TextParseException, WireParseException { - // absolute name with three 63-char labels and a 62-char label - byte[] raw = new byte[] {63, 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 63, 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', - 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', - 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', - 'b', 'b', 'b', 'b', 'b', 'b', 63, 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', - 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', - 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', - 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 62, 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', - 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', - 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', - 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 'd', 0}; - - try { - new Name(new DnsInput(raw)); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - } - } - - public - void test_max_labels() throws TextParseException, WireParseException { - byte[] raw = new byte[] {1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 0}; - Name e = Name.fromString( - "a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a."); - Name n = new Name(new DnsInput(raw)); - assertEquals(128, n.labels()); - assertEquals(e, n); - } - - public - void test_toomany_labels() throws TextParseException, WireParseException { - byte[] raw = new byte[] {1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', - 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 1, 'a', 0}; - try { - new Name(new DnsInput(raw)); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - } - } - - public - void test_basic_compression() throws TextParseException, WireParseException { - byte[] raw = new byte[] {10, 3, 'a', 'b', 'c', 0, (byte) 0xC0, 1}; - Name e = Name.fromString("abc."); - - DnsInput in = new DnsInput(raw); - in.jump(6); - - Options.set("verbosecompression"); - Name n = new Name(in); - Options.unset("verbosecompression"); - assertEquals(e, n); - } - - public - void test_two_pointer_compression() throws TextParseException, WireParseException { - byte[] raw = new byte[] {10, 3, 'a', 'b', 'c', 0, (byte) 0xC0, 1, (byte) 0xC0, 6}; - Name e = Name.fromString("abc."); - - DnsInput in = new DnsInput(raw); - in.jump(8); - - Name n = new Name(in); - assertEquals(e, n); - } - - public - void test_two_part_compression() throws TextParseException, WireParseException { - byte[] raw = new byte[] {10, 3, 'a', 'b', 'c', 0, 1, 'B', (byte) 0xC0, 1}; - Name e = Name.fromString("B.abc."); - - DnsInput in = new DnsInput(raw); - in.jump(6); - - Name n = new Name(in); - assertEquals(e, n); - } - - public - void test_long_jump_compression() throws TextParseException, WireParseException { - // pointer to name beginning at index 256 - byte[] raw = new byte[] {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 3, 'a', 'b', - 'c', 0, (byte) 0xC1, 0}; - Name e = Name.fromString("abc."); - - DnsInput in = new DnsInput(raw); - in.jump(261); - Name n = new Name(in); - assertEquals(e, n); - } - - public - void test_bad_compression() throws TextParseException, WireParseException { - byte[] raw = new byte[] {(byte) 0xC0, 2, 0}; - try { - new Name(new DnsInput(raw)); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - } - } - - public - void test_basic_compression_state_restore() throws TextParseException, WireParseException { - byte[] raw = new byte[] {10, 3, 'a', 'b', 'c', 0, (byte) 0xC0, 1, 3, 'd', 'e', 'f', 0}; - Name e = Name.fromString("abc."); - Name e2 = Name.fromString("def."); - - DnsInput in = new DnsInput(raw); - in.jump(6); - - Name n = new Name(in); - assertEquals(e, n); - - n = new Name(in); - assertEquals(e2, n); - } - - public - void test_two_part_compression_state_restore() throws TextParseException, WireParseException { - byte[] raw = new byte[] {10, 3, 'a', 'b', 'c', 0, 1, 'B', (byte) 0xC0, 1, 3, 'd', 'e', 'f', 0}; - Name e = Name.fromString("B.abc."); - Name e2 = Name.fromString("def."); - - DnsInput in = new DnsInput(raw); - in.jump(6); - - Name n = new Name(in); - assertEquals(e, n); - - n = new Name(in); - assertEquals(e2, n); - } - } - - public - void test_init_from_name() throws TextParseException { - Name n = new Name("A.B.c.d."); - Name e = new Name("B.c.d."); - Name o = new Name(n, 1); - assertEquals(e, o); - } - - public - void test_init_from_name_root() throws TextParseException { - Name n = new Name("A.B.c.d."); - Name o = new Name(n, 4); - assertEquals(Name.root, o); - } - - public - void test_init_from_name_empty() throws TextParseException { - Name n = new Name("A.B.c.d."); - Name n2 = new Name(n, 5); - - assertFalse(n2.isAbsolute()); - assertFalse(n2.isWild()); - assertEquals(0, n2.labels()); - assertEquals(0, n2.length()); - } - - public - void test_concatenate_basic() throws NameTooLongException, TextParseException { - Name p = Name.fromString("A.B"); - Name s = Name.fromString("c.d."); - Name e = Name.fromString("A.B.c.d."); - - Name n = Name.concatenate(p, s); - assertEquals(e, n); - } - - public - void test_concatenate_abs_prefix() throws NameTooLongException, TextParseException { - Name p = Name.fromString("A.B."); - Name s = Name.fromString("c.d."); - Name e = Name.fromString("A.B."); - - Name n = Name.concatenate(p, s); - assertEquals(e, n); - } - - public - void test_concatenate_too_long() throws TextParseException { - Name p = Name.fromString( - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); - Name s = Name.fromString( - "ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc.ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd."); - - try { - Name.concatenate(p, s); - fail("NameTooLongException not thrown"); - } catch (NameTooLongException e) { - } - } - - public - void test_relativize() throws TextParseException { - Name sub = Name.fromString("a.b.c."); - Name dom = Name.fromString("c."); - Name exp = Name.fromString("a.b"); - - Name n = sub.relativize(dom); - assertEquals(exp, n); - } - - public - void test_relativize_null_origin() throws TextParseException { - Name sub = Name.fromString("a.b.c."); - Name dom = null; - - Name n = sub.relativize(dom); - assertEquals(sub, n); - } - - public - void test_relativize_disjoint() throws TextParseException { - Name sub = Name.fromString("a.b.c."); - Name dom = Name.fromString("e.f."); - - Name n = sub.relativize(dom); - assertEquals(sub, n); - } - - public - void test_relativize_root() throws TextParseException { - Name sub = Name.fromString("a.b.c."); - Name dom = Name.fromString("."); - Name exp = Name.fromString("a.b.c"); - - Name n = sub.relativize(dom); - assertEquals(exp, n); - } - - public - void test_wild() throws TextParseException { - Name sub = Name.fromString("a.b.c."); - Name exp = Name.fromString("*.b.c."); - - Name n = sub.wild(1); - assertEquals(exp, n); - } - - public - void test_parent() throws TextParseException { - Name dom = Name.fromString("a.b.c."); - Name exp = Name.fromString("b.c."); - - Name n = dom.parent(1); - assertEquals(exp, n); - } - - public - void test_wild_abs() throws TextParseException { - Name sub = Name.fromString("a.b.c."); - Name exp = Name.fromString("*."); - - Name n = sub.wild(3); - assertEquals(exp, n); - } - - public - void test_wild_toobig() throws TextParseException { - Name sub = Name.fromString("a.b.c."); - try { - sub.wild(4); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_wild_toosmall() throws TextParseException { - Name sub = Name.fromString("a.b.c."); - try { - sub.wild(0); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_fromDNAME() throws NameTooLongException, TextParseException { - Name own = new Name("the.owner."); - Name alias = new Name("the.alias."); - DNAMERecord dnr = new DNAMERecord(own, DnsClass.IN, 0xABCD, alias); - Name sub = new Name("sub.the.owner."); - Name exp = new Name("sub.the.alias."); - - Name n = sub.fromDNAME(dnr); - assertEquals(exp, n); - } - - public - void test_fromDNAME_toobig() throws NameTooLongException, TextParseException { - Name own = new Name("the.owner."); - Name alias = new Name("the.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc."); - DNAMERecord dnr = new DNAMERecord(own, DnsClass.IN, 0xABCD, alias); - Name sub = new Name("ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.the.owner."); - - try { - sub.fromDNAME(dnr); - fail("NameTooLongException not thrown"); - } catch (NameTooLongException e) { - } - } - - public - void test_fromDNAME_disjoint() throws NameTooLongException, TextParseException { - Name own = new Name("the.owner."); - Name alias = new Name("the.alias."); - DNAMERecord dnr = new DNAMERecord(own, DnsClass.IN, 0xABCD, alias); - - Name sub = new Name("sub.the.other"); - - assertNull(sub.fromDNAME(dnr)); - } - - public - void test_subdomain_abs() throws TextParseException { - Name dom = new Name("the.domain."); - Name sub = new Name("sub.of.the.domain."); - assertTrue(sub.subdomain(dom)); - assertFalse(dom.subdomain(sub)); - } - - public - void test_subdomain_rel() throws TextParseException { - Name dom = new Name("the.domain"); - Name sub = new Name("sub.of.the.domain"); - assertTrue(sub.subdomain(dom)); - assertFalse(dom.subdomain(sub)); - } - - public - void test_subdomain_equal() throws TextParseException { - Name dom = new Name("the.domain"); - Name sub = new Name("the.domain"); - assertTrue(sub.subdomain(dom)); - assertTrue(dom.subdomain(sub)); - } - - public - void test_toString_abs() throws TextParseException { - String in = "This.Is.My.Absolute.Name."; - Name n = new Name(in); - - assertEquals(in, n.toString()); - } - - public - void test_toString_rel() throws TextParseException { - String in = "This.Is.My.Relative.Name"; - Name n = new Name(in); - - assertEquals(in, n.toString()); - } - - public - void test_toString_at() throws TextParseException { - Name n = new Name("@", null); - assertEquals("@", n.toString()); - } - - public - void test_toString_root() throws TextParseException { - assertEquals(".", Name.root.toString()); - } - - public - void test_toString_wild() throws TextParseException { - String in = "*.A.b.c.e"; - Name n = new Name(in); - assertEquals(in, n.toString()); - } - - public - void test_toString_escaped() throws TextParseException { - String in = "my.escaped.junk\\128.label."; - Name n = new Name(in); - assertEquals(in, n.toString()); - } - - public - void test_toString_special_char() throws TextParseException, WireParseException { - byte[] raw = new byte[] {1, '"', 1, '(', 1, ')', 1, '.', 1, ';', 1, '\\', 1, '@', 1, '$', 0}; - String exp = "\\\".\\(.\\).\\..\\;.\\\\.\\@.\\$."; - Name n = new Name(new DnsInput(raw)); - assertEquals(exp, n.toString()); - } - - public static - class Test_toWire extends TestCase { - public - void test_rel() throws TextParseException { - Name n = new Name("A.Relative.Name"); - try { - n.toWire(new DnsOutput(), null); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_null_Compression() throws TextParseException { - byte[] raw = new byte[] {1, 'A', 5, 'B', 'a', 's', 'i', 'c', 4, 'N', 'a', 'm', 'e', 0}; - Name n = new Name("A.Basic.Name."); - - DnsOutput o = new DnsOutput(); - n.toWire(o, null); - - assertTrue(Arrays.equals(raw, o.toByteArray())); - } - - public - void test_empty_Compression() throws TextParseException { - byte[] raw = new byte[] {1, 'A', 5, 'B', 'a', 's', 'i', 'c', 4, 'N', 'a', 'm', 'e', 0}; - Name n = new Name("A.Basic.Name."); - - Compression c = new Compression(); - DnsOutput o = new DnsOutput(); - n.toWire(o, c); - - assertTrue(Arrays.equals(raw, o.toByteArray())); - assertEquals(0, c.get(n)); - } - - public - void test_with_exact_Compression() throws TextParseException { - Name n = new Name("A.Basic.Name."); - - Compression c = new Compression(); - c.add(256, n); - byte[] exp = new byte[] {(byte) 0xC1, 0x0}; - - DnsOutput o = new DnsOutput(); - n.toWire(o, c); - assertTrue(Arrays.equals(exp, o.toByteArray())); - assertEquals(256, c.get(n)); - } - - public - void test_with_partial_Compression() throws TextParseException { - Name d = new Name("Basic.Name."); - Name n = new Name("A.Basic.Name."); - - Compression c = new Compression(); - c.add(257, d); - byte[] exp = new byte[] {1, 'A', (byte) 0xC1, 0x1}; - - DnsOutput o = new DnsOutput(); - n.toWire(o, c); - assertTrue(Arrays.equals(exp, o.toByteArray())); - assertEquals(257, c.get(d)); - assertEquals(0, c.get(n)); - } - - public - void test_0arg_rel() throws TextParseException { - Name n = new Name("A.Relative.Name"); - try { - n.toWire(); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_0arg() throws TextParseException { - byte[] raw = new byte[] {1, 'A', 5, 'B', 'a', 's', 'i', 'c', 4, 'N', 'a', 'm', 'e', 0}; - Name n = new Name("A.Basic.Name."); - - byte[] out = n.toWire(); - - assertTrue(Arrays.equals(raw, out)); - } - - public - void test_root() { - byte[] out = Name.root.toWire(); - assertTrue(Arrays.equals(new byte[] {0}, out)); - } - - public - void test_3arg() throws TextParseException { - Name d = new Name("Basic.Name."); - Name n = new Name("A.Basic.Name."); - - Compression c = new Compression(); - c.add(257, d); - byte[] exp = new byte[] {1, 'A', (byte) 0xC1, 0x1}; - - DnsOutput o = new DnsOutput(); - n.toWire(o, c, false); - assertTrue(Arrays.equals(exp, o.toByteArray())); - assertEquals(257, c.get(d)); - assertEquals(0, c.get(n)); - } - } - - - public static - class Test_toWireCanonical extends TestCase { - public - void test_basic() throws TextParseException { - byte[] raw = new byte[] {1, 'a', 5, 'b', 'a', 's', 'i', 'c', 4, 'n', 'a', 'm', 'e', 0}; - Name n = new Name("A.Basic.Name."); - - DnsOutput o = new DnsOutput(); - n.toWireCanonical(o); - - assertTrue(Arrays.equals(raw, o.toByteArray())); - } - - public - void test_0arg() throws TextParseException { - byte[] raw = new byte[] {1, 'a', 5, 'b', 'a', 's', 'i', 'c', 4, 'n', 'a', 'm', 'e', 0}; - Name n = new Name("A.Basic.Name."); - - byte[] out = n.toWireCanonical(); - - assertTrue(Arrays.equals(raw, out)); - } - - public - void test_root() { - byte[] out = Name.root.toWireCanonical(); - assertTrue(Arrays.equals(new byte[] {0}, out)); - } - - public - void test_empty() throws TextParseException { - Name n = new Name("@", null); - byte[] out = n.toWireCanonical(); - assertTrue(Arrays.equals(new byte[0], out)); - } - - public - void test_3arg() throws TextParseException { - Name d = new Name("Basic.Name."); - Name n = new Name("A.Basic.Name."); - - Compression c = new Compression(); - c.add(257, d); - byte[] exp = new byte[] {1, 'a', 5, 'b', 'a', 's', 'i', 'c', 4, 'n', 'a', 'm', 'e', 0}; - - DnsOutput o = new DnsOutput(); - n.toWire(o, c, true); - assertTrue(Arrays.equals(exp, o.toByteArray())); - assertEquals(257, c.get(d)); - assertEquals(-1, c.get(n)); - } - } - - - public static - class Test_equals extends TestCase { - public - void test_same() throws TextParseException { - Name n = new Name("A.Name."); - assertTrue(n.equals(n)); - } - - public - void test_null() throws TextParseException { - Name n = new Name("A.Name."); - assertFalse(n.equals(null)); - } - - public - void test_notName() throws TextParseException { - Name n = new Name("A.Name."); - assertFalse(n.equals(new Object())); - } - - public - void test_abs() throws TextParseException { - Name n = new Name("A.Name."); - Name n2 = new Name("a.name."); - - assertTrue(n.equals(n2)); - assertTrue(n2.equals(n)); - } - - public - void test_rel() throws TextParseException { - Name n1 = new Name("A.Relative.Name"); - Name n2 = new Name("a.relative.name"); - - assertTrue(n1.equals(n2)); - assertTrue(n2.equals(n1)); - } - - public - void test_mixed() throws TextParseException { - Name n1 = new Name("A.Name"); - Name n2 = new Name("a.name."); - - assertFalse(n1.equals(n2)); - assertFalse(n2.equals(n1)); - } - - public - void test_weird() throws TextParseException { - Name n1 = new Name("ab.c"); - Name n2 = new Name("abc."); - - assertFalse(n1.equals(n2)); - assertFalse(n2.equals(n1)); - } - } - - - public static - class Test_compareTo extends TestCase { - public - void test_notName() throws TextParseException { - Name n = new Name("A.Name"); - try { - n.compareTo(new Object()); - fail("ClassCastException not thrown"); - } catch (ClassCastException e) { - } - } - - public - void test_same() throws TextParseException { - Name n = new Name("A.Name"); - assertEquals(0, n.compareTo(n)); - } - - public - void test_equal() throws TextParseException { - Name n1 = new Name("A.Name."); - Name n2 = new Name("a.name."); - - assertEquals(0, n1.compareTo(n2)); - assertEquals(0, n2.compareTo(n1)); - } - - public - void test_close() throws TextParseException { - Name n1 = new Name("a.name"); - Name n2 = new Name("a.name."); - - assertTrue(n1.compareTo(n2) > 0); - assertTrue(n2.compareTo(n1) < 0); - } - - public - void test_disjoint() throws TextParseException { - Name n1 = new Name("b"); - Name n2 = new Name("c"); - - assertTrue(n1.compareTo(n2) < 0); - assertTrue(n2.compareTo(n1) > 0); - } - - public - void test_label_prefix() throws TextParseException { - Name n1 = new Name("thisIs.a."); - Name n2 = new Name("thisIsGreater.a."); - - assertTrue(n1.compareTo(n2) < 0); - assertTrue(n2.compareTo(n1) > 0); - } - - public - void test_more_labels() throws TextParseException { - Name n1 = new Name("c.b.a."); - Name n2 = new Name("d.c.b.a."); - - assertTrue(n1.compareTo(n2) < 0); - assertTrue(n2.compareTo(n1) > 0); - } - } - - public - void test_canonicalize() throws TextParseException { - Name n1 = new Name("ABC.com"); - Name n2 = new Name("abc.com"); - Name n3 = new Name("\\193.com"); - - Name cn1 = n1.canonicalize(); - Name cn2 = n2.canonicalize(); - Name cn3 = n3.canonicalize(); - - assertNotSame(n1, cn1); - assertEquals(n1, cn1); - assertSame(n2, cn2); - assertSame(n3, cn3); - assertEquals(cn1.toString(), cn2.toString()); - assertFalse(n1.toString() - .equals(n2.toString())); - assertEquals(cn1.toString(), cn2.toString()); - } - - public - void test_to_string() throws TextParseException { - Name n1 = new Name("abc.com"); - Name n2 = new Name("abc.com."); - - assertEquals(n1.toString(true), n1.toString(true)); - assertFalse(n2.toString(true) - .equals(n2.toString(false))); - assertEquals(n2.toString(true) + ".", n2.toString(false)); - assertEquals(Name.root.toString(true), Name.root.toString(false)); - assertEquals(Name.empty.toString(true), Name.empty.toString(false)); - } - - public - void test_absolute() throws TextParseException { - Name n1 = new Name("abc.com"); - Name n2 = new Name("abc.com."); - Name n3 = new Name("abc.com", Name.root); - Name n4 = new Name("abc.com", n1); - Name n5 = new Name("abc.com\\000"); - - assertFalse(n1.isAbsolute()); - assertTrue(n2.isAbsolute()); - assertTrue(n3.isAbsolute()); - assertFalse(n4.isAbsolute()); - assertFalse(n5.isAbsolute()); - } - - public static - Test suite() { - TestSuite s = new TestSuite(); - s.addTestSuite(Test_String_init.class); - s.addTestSuite(Test_DNSInput_init.class); - s.addTestSuite(NameTest.class); - s.addTestSuite(Test_toWire.class); - s.addTestSuite(Test_toWireCanonical.class); - s.addTestSuite(Test_equals.class); - s.addTestSuite(Test_compareTo.class); - return s; - } -} diff --git a/test/dorkbox/network/dns/OpcodeTest.java b/test/dorkbox/network/dns/OpcodeTest.java deleted file mode 100644 index 59c56163..00000000 --- a/test/dorkbox/network/dns/OpcodeTest.java +++ /dev/null @@ -1,82 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import dorkbox.network.dns.constants.DnsOpCode; -import junit.framework.TestCase; - -public -class OpcodeTest extends TestCase { - public - void test_string() { - // a regular one - assertEquals("IQUERY", DnsOpCode.string(DnsOpCode.IQUERY)); - - // one that doesn't exist - assertTrue(DnsOpCode.string(6) - .startsWith("RESERVED")); - - try { - DnsOpCode.string(-1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - - // (max is 0xF) - try { - DnsOpCode.string(0x10); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_value() { - // regular one - assertEquals(DnsOpCode.STATUS, DnsOpCode.value("STATUS")); - - // one thats undefined but within range - assertEquals(6, DnsOpCode.value("RESERVED6")); - - // one thats undefined but out of range - assertEquals(-1, DnsOpCode.value("RESERVED" + 0x10)); - - // something that unknown - assertEquals(-1, DnsOpCode.value("THIS IS DEFINITELY UNKNOWN")); - - // empty string - assertEquals(-1, DnsOpCode.value("")); - } -} diff --git a/test/dorkbox/network/dns/OptionsTest.java b/test/dorkbox/network/dns/OptionsTest.java deleted file mode 100644 index 85719a54..00000000 --- a/test/dorkbox/network/dns/OptionsTest.java +++ /dev/null @@ -1,149 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import dorkbox.network.dns.utils.Options; -import junit.framework.TestCase; - -public -class OptionsTest extends TestCase { - @Override - public - void setUp() { - // reset the options table before each test - Options.clear(); - } - - public - void test_set_1arg() { - Options.set("Option1"); - assertEquals("true", Options.value("option1")); - - Options.set("OPTION2"); - assertEquals("true", Options.value("option1")); - assertEquals("true", Options.value("OpTIOn2")); - - Options.set("option2"); - assertEquals("true", Options.value("option2")); - } - - public - void test_set_2arg() { - Options.set("OPTION1", "Value1"); - assertEquals("value1", Options.value("Option1")); - - Options.set("option2", "value2"); - assertEquals("value1", Options.value("Option1")); - assertEquals("value2", Options.value("OPTION2")); - - Options.set("OPTION2", "value2b"); - assertEquals("value1", Options.value("Option1")); - assertEquals("value2b", Options.value("option2")); - } - - public - void test_check() { - assertFalse(Options.check("No Options yet")); - - Options.set("First Option"); - assertFalse(Options.check("Not a valid option name")); - assertTrue(Options.check("First Option")); - assertTrue(Options.check("FIRST option")); - } - - public - void test_unset() { - // unset something non-existant - Options.unset("Not an option Name"); - - Options.set("Temporary Option"); - assertTrue(Options.check("Temporary Option")); - Options.unset("Temporary Option"); - assertFalse(Options.check("Temporary Option")); - - Options.set("Temporary Option"); - assertTrue(Options.check("Temporary Option")); - Options.unset("temporary option"); - assertFalse(Options.check("Temporary Option")); - - // unset something now that the table is non-null - Options.unset("Still Not an Option Name"); - } - - public - void test_value() { - assertNull(Options.value("Table is Null")); - - Options.set("Testing Option"); - assertNull(Options.value("Not an Option Name")); - - assertEquals("true", Options.value("Testing OPTION")); - } - - public - void test_intValue() { - assertEquals(-1, Options.intValue("Table is Null")); - - Options.set("A Boolean Option"); - Options.set("An Int Option", "13"); - Options.set("Not An Int Option", "NotAnInt"); - Options.set("A Negative Int Value", "-1000"); - - assertEquals(-1, Options.intValue("A Boolean Option")); - assertEquals(-1, Options.intValue("Not an Option NAME")); - assertEquals(13, Options.intValue("an int option")); - assertEquals(-1, Options.intValue("NOT an INT option")); - assertEquals(-1, Options.intValue("A negative int Value")); - } - - public - void test_systemProperty() { - System.setProperty("dnsjava.options", "booleanOption,valuedOption1=10,valuedOption2=NotAnInteger"); - - Options.refresh(); - - assertTrue(Options.check("booleanOPTION")); - assertTrue(Options.check("booleanOption")); - assertTrue(Options.check("valuedOption1")); - assertTrue(Options.check("ValuedOption2")); - - assertEquals("true", Options.value("booleanOption")); - assertEquals(-1, Options.intValue("BOOLEANOPTION")); - assertEquals("10", Options.value("valuedOption1")); - assertEquals(10, Options.intValue("valuedOption1")); - assertEquals("notaninteger", Options.value("VALUEDOPTION2")); - assertEquals(-1, Options.intValue("valuedOption2")); - } -} diff --git a/test/dorkbox/network/dns/RcodeTest.java b/test/dorkbox/network/dns/RcodeTest.java deleted file mode 100644 index 867a1cfc..00000000 --- a/test/dorkbox/network/dns/RcodeTest.java +++ /dev/null @@ -1,112 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import dorkbox.network.dns.constants.DnsResponseCode; -import junit.framework.TestCase; - -public -class RcodeTest extends TestCase { - public - void test_string() { - // a regular one - assertEquals("NXDOMAIN", DnsResponseCode.string(DnsResponseCode.NXDOMAIN)); - - // one with an alias - assertEquals("NOTIMP", DnsResponseCode.string(DnsResponseCode.NOTIMP)); - - // one that doesn't exist - assertTrue(DnsResponseCode.string(20) - .startsWith("RESERVED")); - - try { - DnsResponseCode.string(-1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - - // (max is 0xFFF) - try { - DnsResponseCode.string(0x1000); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_TSIGstring() { - // a regular one - assertEquals("BADSIG", DnsResponseCode.TSIGstring(DnsResponseCode.BADSIG)); - - // one that doesn't exist - assertTrue(DnsResponseCode.TSIGstring(22) - .startsWith("RESERVED")); - - try { - DnsResponseCode.TSIGstring(-1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - - // (max is 0xFFFF) - try { - DnsResponseCode.string(0x10000); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_value() { - // regular one - assertEquals(DnsResponseCode.FORMERR, DnsResponseCode.value("FORMERR")); - - // one with alias - assertEquals(DnsResponseCode.NOTIMP, DnsResponseCode.value("NOTIMP")); - assertEquals(DnsResponseCode.NOTIMP, DnsResponseCode.value("NOTIMPL")); - - // one thats undefined but within range - assertEquals(35, DnsResponseCode.value("RESERVED35")); - - // one thats undefined but out of range - assertEquals(-1, DnsResponseCode.value("RESERVED" + 0x1000)); - - // something that unknown - assertEquals(-1, DnsResponseCode.value("THIS IS DEFINITELY UNKNOWN")); - - // empty string - assertEquals(-1, DnsResponseCode.value("")); - } -} diff --git a/test/dorkbox/network/dns/ReverseMapTest.java b/test/dorkbox/network/dns/ReverseMapTest.java deleted file mode 100644 index eb5c000a..00000000 --- a/test/dorkbox/network/dns/ReverseMapTest.java +++ /dev/null @@ -1,114 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Address; -import dorkbox.network.dns.utils.ReverseMap; -import junit.framework.TestCase; - -public -class ReverseMapTest extends TestCase { - public - void test_fromAddress_ipv4() throws UnknownHostException, TextParseException { - Name exp = Name.fromString("1.0.168.192.in-addr.arpa."); - String addr = "192.168.0.1"; - assertEquals(exp, ReverseMap.fromAddress(addr)); - - assertEquals(exp, ReverseMap.fromAddress(addr, Address.IPv4)); - assertEquals(exp, ReverseMap.fromAddress(InetAddress.getByName(addr))); - assertEquals(exp, ReverseMap.fromAddress(new byte[] {(byte) 192, (byte) 168, (byte) 0, (byte) 1})); - assertEquals(exp, ReverseMap.fromAddress(new int[] {192, 168, 0, 1})); - } - - public - void test_fromAddress_ipv6() throws UnknownHostException, TextParseException { - Name exp = Name.fromString("4.3.3.7.0.7.3.0.E.2.A.8.9.1.3.1.3.D.8.0.3.A.5.8.8.B.D.0.1.0.0.2.ip6.arpa."); - String addr = "2001:0db8:85a3:08d3:1319:8a2e:0370:7334"; - byte[] dat = new byte[] {(byte) 32, (byte) 1, (byte) 13, (byte) 184, (byte) 133, (byte) 163, (byte) 8, (byte) 211, (byte) 19, - (byte) 25, (byte) 138, (byte) 46, (byte) 3, (byte) 112, (byte) 115, (byte) 52}; - int[] idat = new int[] {32, 1, 13, 184, 133, 163, 8, 211, 19, 25, 138, 46, 3, 112, 115, 52}; - - - assertEquals(exp, ReverseMap.fromAddress(addr, Address.IPv6)); - assertEquals(exp, ReverseMap.fromAddress(InetAddress.getByName(addr))); - assertEquals(exp, ReverseMap.fromAddress(dat)); - assertEquals(exp, ReverseMap.fromAddress(idat)); - } - - public - void test_fromAddress_invalid() { - try { - ReverseMap.fromAddress("A.B.C.D", Address.IPv4); - fail("UnknownHostException not thrown"); - } catch (UnknownHostException e) { - } - try { - ReverseMap.fromAddress(new byte[0]); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - ReverseMap.fromAddress(new byte[3]); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - ReverseMap.fromAddress(new byte[5]); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - ReverseMap.fromAddress(new byte[15]); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - ReverseMap.fromAddress(new byte[17]); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - - try { - int[] dat = new int[] {0, 1, 2, 256}; - ReverseMap.fromAddress(dat); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } -} diff --git a/test/dorkbox/network/dns/TokenizerTest.java b/test/dorkbox/network/dns/TokenizerTest.java deleted file mode 100644 index 54fb397b..00000000 --- a/test/dorkbox/network/dns/TokenizerTest.java +++ /dev/null @@ -1,609 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; - -import dorkbox.network.dns.exceptions.RelativeNameException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.records.TTL; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.TestCase; - -public -class TokenizerTest extends TestCase { - private Tokenizer m_t; - - @Override - protected - void setUp() { - m_t = null; - } - - public - void test_get() throws IOException { - m_t = new Tokenizer(new BufferedInputStream(new ByteArrayInputStream("AnIdentifier \"a quoted \\\" string\"\r\n; this is \"my\"\t(comment)\nanotherIdentifier (\ramultilineIdentifier\n)".getBytes()))); - - Tokenizer.Token tt = m_t.get(true, true); - assertEquals(Tokenizer.IDENTIFIER, tt.type); - assertTrue(tt.isString()); - assertFalse(tt.isEOL()); - assertEquals("AnIdentifier", tt.value); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.WHITESPACE, tt.type); - assertFalse(tt.isString()); - assertFalse(tt.isEOL()); - assertNull(tt.value); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.QUOTED_STRING, tt.type); - assertTrue(tt.isString()); - assertFalse(tt.isEOL()); - assertEquals("a quoted \\\" string", tt.value); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.EOL, tt.type); - assertFalse(tt.isString()); - assertTrue(tt.isEOL()); - assertNull(tt.value); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.COMMENT, tt.type); - assertFalse(tt.isString()); - assertFalse(tt.isEOL()); - assertEquals(" this is \"my\"\t(comment)", tt.value); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.EOL, tt.type); - assertFalse(tt.isString()); - assertTrue(tt.isEOL()); - assertNull(tt.value); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.IDENTIFIER, tt.type); - assertTrue(tt.isString()); - assertFalse(tt.isEOL()); - assertEquals("anotherIdentifier", tt.value); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.WHITESPACE, tt.type); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.IDENTIFIER, tt.type); - assertTrue(tt.isString()); - assertFalse(tt.isEOL()); - assertEquals("amultilineIdentifier", tt.value); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.WHITESPACE, tt.type); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.EOF, tt.type); - assertFalse(tt.isString()); - assertTrue(tt.isEOL()); - assertNull(tt.value); - - // should be able to do this repeatedly - tt = m_t.get(true, true); - assertEquals(Tokenizer.EOF, tt.type); - assertFalse(tt.isString()); - assertTrue(tt.isEOL()); - assertNull(tt.value); - - m_t = new Tokenizer("onlyOneIdentifier"); - tt = m_t.get(); - assertEquals(Tokenizer.IDENTIFIER, tt.type); - assertEquals("onlyOneIdentifier", tt.value); - - m_t = new Tokenizer("identifier ;"); - tt = m_t.get(); - assertEquals("identifier", tt.value); - tt = m_t.get(); - assertEquals(Tokenizer.EOF, tt.type); - - - // some ungets - m_t = new Tokenizer("identifier \nidentifier2; junk comment"); - tt = m_t.get(true, true); - assertEquals(Tokenizer.IDENTIFIER, tt.type); - assertEquals("identifier", tt.value); - - m_t.unget(); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.IDENTIFIER, tt.type); - assertEquals("identifier", tt.value); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.WHITESPACE, tt.type); - - m_t.unget(); - tt = m_t.get(true, true); - assertEquals(Tokenizer.WHITESPACE, tt.type); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.EOL, tt.type); - - m_t.unget(); - tt = m_t.get(true, true); - assertEquals(Tokenizer.EOL, tt.type); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.IDENTIFIER, tt.type); - assertEquals("identifier2", tt.value); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.COMMENT, tt.type); - assertEquals(" junk comment", tt.value); - - m_t.unget(); - tt = m_t.get(true, true); - assertEquals(Tokenizer.COMMENT, tt.type); - assertEquals(" junk comment", tt.value); - - tt = m_t.get(true, true); - assertEquals(Tokenizer.EOF, tt.type); - - m_t = new Tokenizer("identifier ( junk ; comment\n )"); - tt = m_t.get(); - assertEquals(Tokenizer.IDENTIFIER, tt.type); - assertEquals(Tokenizer.IDENTIFIER, m_t.get().type); - assertEquals(Tokenizer.EOF, m_t.get().type); - } - - public - void test_get_invalid() throws IOException { - m_t = new Tokenizer("(this ;"); - m_t.get(); - try { - m_t.get(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - m_t = new Tokenizer("\"bad"); - try { - m_t.get(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - m_t = new Tokenizer(")"); - try { - m_t.get(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - m_t = new Tokenizer("\\"); - try { - m_t.get(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - m_t = new Tokenizer("\"\n"); - try { - m_t.get(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_File_input() throws IOException { - File tmp = File.createTempFile("dnsjava", "tmp"); - try { - FileWriter fw = new FileWriter(tmp); - fw.write("file\ninput; test"); - fw.close(); - - m_t = new Tokenizer(tmp); - - Tokenizer.Token tt = m_t.get(); - assertEquals(Tokenizer.IDENTIFIER, tt.type); - assertEquals("file", tt.value); - - tt = m_t.get(); - assertEquals(Tokenizer.EOL, tt.type); - - tt = m_t.get(); - assertEquals(Tokenizer.IDENTIFIER, tt.type); - assertEquals("input", tt.value); - - tt = m_t.get(false, true); - assertEquals(Tokenizer.COMMENT, tt.type); - assertEquals(" test", tt.value); - - m_t.close(); - } finally { - tmp.delete(); - } - } - - public - void test_unwanted_comment() throws IOException { - m_t = new Tokenizer("; this whole thing is a comment\n"); - Tokenizer.Token tt = m_t.get(); - - assertEquals(Tokenizer.EOL, tt.type); - } - - public - void test_unwanted_ungotten_whitespace() throws IOException { - m_t = new Tokenizer(" "); - Tokenizer.Token tt = m_t.get(true, true); - m_t.unget(); - tt = m_t.get(); - assertEquals(Tokenizer.EOF, tt.type); - } - - public - void test_unwanted_ungotten_comment() throws IOException { - m_t = new Tokenizer("; this whole thing is a comment"); - Tokenizer.Token tt = m_t.get(true, true); - m_t.unget(); - tt = m_t.get(); - assertEquals(Tokenizer.EOF, tt.type); - } - - public - void test_empty_string() throws IOException { - m_t = new Tokenizer(""); - Tokenizer.Token tt = m_t.get(); - assertEquals(Tokenizer.EOF, tt.type); - - m_t = new Tokenizer(" "); - tt = m_t.get(); - assertEquals(Tokenizer.EOF, tt.type); - } - - public - void test_multiple_ungets() throws IOException { - m_t = new Tokenizer("a simple one"); - Tokenizer.Token tt = m_t.get(); - - m_t.unget(); - try { - m_t.unget(); - fail("IllegalStateException not thrown"); - } catch (IllegalStateException e) { - } - } - - public - void test_getString() throws IOException { - m_t = new Tokenizer("just_an_identifier"); - String out = m_t.getString(); - assertEquals("just_an_identifier", out); - - m_t = new Tokenizer("\"just a string\""); - out = m_t.getString(); - assertEquals("just a string", out); - - m_t = new Tokenizer("; just a comment"); - try { - out = m_t.getString(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_getIdentifier() throws IOException { - m_t = new Tokenizer("just_an_identifier"); - String out = m_t.getIdentifier(); - assertEquals("just_an_identifier", out); - - m_t = new Tokenizer("\"just a string\""); - try { - m_t.getIdentifier(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_getLong() throws IOException { - m_t = new Tokenizer((Integer.MAX_VALUE + 1L) + ""); - long out = m_t.getLong(); - assertEquals((Integer.MAX_VALUE + 1L), out); - - m_t = new Tokenizer("-10"); - try { - m_t.getLong(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - m_t = new Tokenizer("19_identifier"); - try { - m_t.getLong(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_getUInt32() throws IOException { - m_t = new Tokenizer(0xABCDEF12L + ""); - long out = m_t.getUInt32(); - assertEquals(0xABCDEF12L, out); - - m_t = new Tokenizer(0x100000000L + ""); - try { - m_t.getUInt32(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - m_t = new Tokenizer("-12345"); - try { - m_t.getUInt32(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_getUInt16() throws IOException { - m_t = new Tokenizer(0xABCDL + ""); - int out = m_t.getUInt16(); - assertEquals(0xABCDL, out); - - m_t = new Tokenizer(0x10000 + ""); - try { - m_t.getUInt16(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - m_t = new Tokenizer("-125"); - try { - m_t.getUInt16(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_getUInt8() throws IOException { - m_t = new Tokenizer(0xCDL + ""); - int out = m_t.getUInt8(); - assertEquals(0xCDL, out); - - m_t = new Tokenizer(0x100 + ""); - try { - m_t.getUInt8(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - m_t = new Tokenizer("-12"); - try { - m_t.getUInt8(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_getTTL() throws IOException { - m_t = new Tokenizer("59S"); - assertEquals(59, m_t.getTTL()); - - m_t = new Tokenizer(TTL.MAX_VALUE + ""); - assertEquals(TTL.MAX_VALUE, m_t.getTTL()); - - m_t = new Tokenizer((TTL.MAX_VALUE + 1L) + ""); - assertEquals(TTL.MAX_VALUE, m_t.getTTL()); - - m_t = new Tokenizer("Junk"); - try { - m_t.getTTL(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_getTTLLike() throws IOException { - m_t = new Tokenizer("59S"); - assertEquals(59, m_t.getTTLLike()); - - m_t = new Tokenizer(TTL.MAX_VALUE + ""); - assertEquals(TTL.MAX_VALUE, m_t.getTTLLike()); - - m_t = new Tokenizer((TTL.MAX_VALUE + 1L) + ""); - assertEquals(TTL.MAX_VALUE + 1L, m_t.getTTLLike()); - - m_t = new Tokenizer("Junk"); - try { - m_t.getTTLLike(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_getName() throws IOException, TextParseException { - Name root = Name.fromString("."); - m_t = new Tokenizer("junk"); - Name exp = Name.fromString("junk."); - Name out = m_t.getName(root); - assertEquals(exp, out); - - Name rel = Name.fromString("you.dig"); - m_t = new Tokenizer("junk"); - try { - m_t.getName(rel); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException e) { - } - - m_t = new Tokenizer(""); - try { - m_t.getName(root); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_getEOL() throws IOException { - m_t = new Tokenizer("id"); - m_t.getIdentifier(); - try { - m_t.getEOL(); - } catch (TextParseException e) { - fail(e.getMessage()); - } - - m_t = new Tokenizer("\n"); - try { - m_t.getEOL(); - m_t.getEOL(); - } catch (TextParseException e) { - fail(e.getMessage()); - } - - m_t = new Tokenizer("id"); - try { - m_t.getEOL(); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_getBase64() throws IOException { - byte[] exp = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - // basic - m_t = new Tokenizer("AQIDBAUGBwgJ"); - byte[] out = m_t.getBase64(); - assertEquals(exp, out); - - // with some whitespace - m_t = new Tokenizer("AQIDB AUGB wgJ"); - out = m_t.getBase64(); - assertEquals(exp, out); - - // two base64s separated by newline - m_t = new Tokenizer("AQIDBAUGBwgJ\nAB23DK"); - out = m_t.getBase64(); - assertEquals(exp, out); - - // no remaining strings - m_t = new Tokenizer("\n"); - assertNull(m_t.getBase64()); - - m_t = new Tokenizer("\n"); - try { - m_t.getBase64(true); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - // invalid encoding - m_t = new Tokenizer("not_base64"); - try { - m_t.getBase64(false); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - m_t = new Tokenizer("not_base64"); - try { - m_t.getBase64(true); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - private - void assertEquals(byte[] exp, byte[] act) { - assertTrue(java.util.Arrays.equals(exp, act)); - } - - public - void test_getHex() throws IOException { - byte[] exp = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - // basic - m_t = new Tokenizer("0102030405060708090A0B0C0D0E0F"); - byte[] out = m_t.getHex(); - assertEquals(exp, out); - - // with some whitespace - m_t = new Tokenizer("0102030 405 060708090A0B0C 0D0E0F"); - out = m_t.getHex(); - assertEquals(exp, out); - - // two hexs separated by newline - m_t = new Tokenizer("0102030405060708090A0B0C0D0E0F\n01AB3FE"); - out = m_t.getHex(); - assertEquals(exp, out); - - // no remaining strings - m_t = new Tokenizer("\n"); - assertNull(m_t.getHex()); - - m_t = new Tokenizer("\n"); - try { - m_t.getHex(true); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - // invalid encoding - m_t = new Tokenizer("not_hex"); - try { - m_t.getHex(false); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - m_t = new Tokenizer("not_hex"); - try { - m_t.getHex(true); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } -} diff --git a/test/dorkbox/network/dns/TypeTest.java b/test/dorkbox/network/dns/TypeTest.java deleted file mode 100644 index 799a5b6f..00000000 --- a/test/dorkbox/network/dns/TypeTest.java +++ /dev/null @@ -1,83 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns; - -import dorkbox.network.dns.constants.DnsRecordType; -import junit.framework.TestCase; - -public -class TypeTest extends TestCase { - public - void test_string() { - // a regular one - assertEquals("CNAME", DnsRecordType.string(DnsRecordType.CNAME)); - - // one that doesn't exist - assertTrue(DnsRecordType.string(65535) - .startsWith("TYPE")); - - try { - DnsRecordType.string(-1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_value() { - // regular one - assertEquals(DnsRecordType.MAILB, DnsRecordType.value("MAILB")); - - // one thats undefined but within range - assertEquals(300, DnsRecordType.value("TYPE300")); - - // something that unknown - assertEquals(-1, DnsRecordType.value("THIS IS DEFINITELY UNKNOWN")); - - // empty string - assertEquals(-1, DnsRecordType.value("")); - } - - public - void test_value_2arg() { - assertEquals(301, DnsRecordType.value("301", true)); - } - - public - void test_isRR() { - assertTrue(DnsRecordType.isRR(DnsRecordType.CNAME)); - assertFalse(DnsRecordType.isRR(DnsRecordType.IXFR)); - } -} diff --git a/test/dorkbox/network/dns/ZoneDatabaseTest.java b/test/dorkbox/network/dns/ZoneDatabaseTest.java deleted file mode 100644 index 9cda933c..00000000 --- a/test/dorkbox/network/dns/ZoneDatabaseTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2018 dorkbox, llc. - * - * 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 dorkbox.network.dns; - -import org.junit.Test; - -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.server.Response; -import dorkbox.network.dns.zone.AbstractZone; -import dorkbox.network.dns.zone.ZoneDatabase; -import dorkbox.network.dns.zone.ZoneType; -import junit.framework.TestCase; - -public -class ZoneDatabaseTest extends TestCase { - - class TestZone extends AbstractZone { - public - TestZone(String name) throws TextParseException { - super(ZoneType.master, Name.fromString(name)); - } - - @Override - public - Response find(final Name qname, final int recordType) { - return null; - } - } - - @Test - public - void testFind() throws TextParseException { - ZoneDatabase db = new ZoneDatabase(); - db.add(new TestZone("example.com.")); - db.add(new TestZone("example.co.jp.")); - db.add(new TestZone("jp.")); - db.add(new TestZone("ne.jp.")); - - assertNotNull(db.prepare(Name.fromString("jp."), DnsClass.IN)); - assertNull(db.prepare(Name.fromString("com."), DnsClass.IN)); - } -} diff --git a/test/dorkbox/network/dns/records/A6RecordTest.java b/test/dorkbox/network/dns/records/A6RecordTest.java deleted file mode 100644 index a14c4dc1..00000000 --- a/test/dorkbox/network/dns/records/A6RecordTest.java +++ /dev/null @@ -1,253 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.RelativeNameException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.TestCase; - -public -class A6RecordTest extends TestCase { - Name m_an, m_an2, m_rn; - InetAddress m_addr; - String m_addr_string, m_addr_string_canonical; - byte[] m_addr_bytes; - int m_prefix_bits; - long m_ttl; - - @Override - protected - void setUp() throws TextParseException, UnknownHostException { - m_an = Name.fromString("My.Absolute.Name."); - m_an2 = Name.fromString("My.Second.Absolute.Name."); - m_rn = Name.fromString("My.Relative.Name"); - m_addr_string = "2001:0db8:85a3:08d3:1319:8a2e:0370:7334"; - m_addr_string_canonical = "2001:db8:85a3:8d3:1319:8a2e:370:7334"; - m_addr = InetAddress.getByName(m_addr_string); - m_addr_bytes = m_addr.getAddress(); - m_ttl = 0x13579; - m_prefix_bits = 9; - } - - public - void test_ctor_0arg() { - A6Record ar = new A6Record(); - assertNull(ar.getName()); - assertEquals(0, ar.getType()); - assertEquals(0, ar.getDClass()); - assertEquals(0, ar.getTTL()); - } - - public - void test_getObject() { - A6Record ar = new A6Record(); - DnsRecord r = ar.getObject(); - assertTrue(r instanceof A6Record); - } - - public - void test_ctor_6arg() { - A6Record ar = new A6Record(m_an, DnsClass.IN, m_ttl, m_prefix_bits, m_addr, null); - assertEquals(m_an, ar.getName()); - assertEquals(DnsRecordType.A6, ar.getType()); - assertEquals(DnsClass.IN, ar.getDClass()); - assertEquals(m_ttl, ar.getTTL()); - assertEquals(m_prefix_bits, ar.getPrefixBits()); - assertEquals(m_addr, ar.getSuffix()); - assertNull(ar.getPrefix()); - - // with the prefix name - ar = new A6Record(m_an, DnsClass.IN, m_ttl, m_prefix_bits, m_addr, m_an2); - assertEquals(m_an, ar.getName()); - assertEquals(DnsRecordType.A6, ar.getType()); - assertEquals(DnsClass.IN, ar.getDClass()); - assertEquals(m_ttl, ar.getTTL()); - assertEquals(m_prefix_bits, ar.getPrefixBits()); - assertEquals(m_addr, ar.getSuffix()); - assertEquals(m_an2, ar.getPrefix()); - - // a relative name - try { - new A6Record(m_rn, DnsClass.IN, m_ttl, m_prefix_bits, m_addr, null); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException e) { - } - - // a relative prefix name - try { - new A6Record(m_an, DnsClass.IN, m_ttl, m_prefix_bits, m_addr, m_rn); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException e) { - } - - // invalid prefix bits - try { - new A6Record(m_rn, DnsClass.IN, m_ttl, 0x100, m_addr, null); - fail("IllegalArgumentException not thrown"); - } catch (RelativeNameException e) { - } - - // an IPv4 address - try { - new A6Record(m_an, DnsClass.IN, m_ttl, m_prefix_bits, InetAddress.getByName("192.168.0.1"), null); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } catch (UnknownHostException e) { - fail(e.getMessage()); - } - } - - public - void test_rrFromWire() throws CloneNotSupportedException, IOException, UnknownHostException { - // record with no prefix - DnsOutput dout = new DnsOutput(); - dout.writeU8(0); - dout.writeByteArray(m_addr_bytes); - - DnsInput din = new DnsInput(dout.toByteArray()); - A6Record ar = new A6Record(); - ar.rrFromWire(din); - assertEquals(0, ar.getPrefixBits()); - assertEquals(m_addr, ar.getSuffix()); - assertNull(ar.getPrefix()); - - // record with 9 bit prefix (should result in 15 bytes of the address) - dout = new DnsOutput(); - dout.writeU8(9); - dout.writeByteArray(m_addr_bytes, 1, 15); - dout.writeByteArray(m_an2.toWire()); - - din = new DnsInput(dout.toByteArray()); - ar = new A6Record(); - ar.rrFromWire(din); - assertEquals(9, ar.getPrefixBits()); - - byte[] addr_bytes = (byte[]) m_addr_bytes.clone(); - addr_bytes[0] = 0; - InetAddress exp = InetAddress.getByAddress(addr_bytes); - assertEquals(exp, ar.getSuffix()); - assertEquals(m_an2, ar.getPrefix()); - } - - public - void test_rdataFromString() throws CloneNotSupportedException, IOException, UnknownHostException { - // record with no prefix - Tokenizer t = new Tokenizer("0 " + m_addr_string); - A6Record ar = new A6Record(); - ar.rdataFromString(t, null); - assertEquals(0, ar.getPrefixBits()); - assertEquals(m_addr, ar.getSuffix()); - assertNull(ar.getPrefix()); - - // record with 9 bit prefix. In contrast to the rrFromWire method, - // rdataFromString expects the entire 128 bits to be represented - // in the string - t = new Tokenizer("9 " + m_addr_string + " " + m_an2); - ar = new A6Record(); - ar.rdataFromString(t, null); - assertEquals(9, ar.getPrefixBits()); - assertEquals(m_addr, ar.getSuffix()); - assertEquals(m_an2, ar.getPrefix()); - - // record with invalid prefixBits - t = new Tokenizer("129"); - ar = new A6Record(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - // record with invalid ipv6 address - t = new Tokenizer("0 " + m_addr_string.substring(4)); - ar = new A6Record(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_rrToString() { - A6Record ar = new A6Record(m_an, DnsClass.IN, m_ttl, m_prefix_bits, m_addr, m_an2); - String exp = "" + m_prefix_bits + " " + m_addr_string_canonical + " " + m_an2; - StringBuilder stringBuilder = new StringBuilder(); - - ar.rrToString(stringBuilder); - String out = stringBuilder.toString(); - assertEquals(exp, out); - } - - public - void test_rrToWire() { - // canonical form - A6Record ar = new A6Record(m_an, DnsClass.IN, m_ttl, m_prefix_bits, m_addr, m_an2); - DnsOutput dout = new DnsOutput(); - dout.writeU8(m_prefix_bits); - dout.writeByteArray(m_addr_bytes, 1, 15); - dout.writeByteArray(m_an2.toWireCanonical()); - - byte[] exp = dout.toByteArray(); - - dout = new DnsOutput(); - ar.rrToWire(dout, null, true); - - assertTrue(Arrays.equals(exp, dout.toByteArray())); - - // case sensitiveform - dout = new DnsOutput(); - dout.writeU8(m_prefix_bits); - dout.writeByteArray(m_addr_bytes, 1, 15); - dout.writeByteArray(m_an2.toWire()); - - exp = dout.toByteArray(); - - dout = new DnsOutput(); - ar.rrToWire(dout, null, false); - assertTrue(Arrays.equals(exp, dout.toByteArray())); - } -} diff --git a/test/dorkbox/network/dns/records/AAAARecordTest.java b/test/dorkbox/network/dns/records/AAAARecordTest.java deleted file mode 100644 index ee8c1588..00000000 --- a/test/dorkbox/network/dns/records/AAAARecordTest.java +++ /dev/null @@ -1,165 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.RelativeNameException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.TestCase; - -public -class AAAARecordTest extends TestCase { - Name m_an, m_rn; - InetAddress m_addr; - String m_addr_string; - byte[] m_addr_bytes; - long m_ttl; - - @Override - protected - void setUp() throws TextParseException, UnknownHostException { - m_an = Name.fromString("My.Absolute.Name."); - m_rn = Name.fromString("My.Relative.Name"); - m_addr_string = "2001:db8:85a3:8d3:1319:8a2e:370:7334"; - m_addr = InetAddress.getByName(m_addr_string); - m_addr_bytes = m_addr.getAddress(); - m_ttl = 0x13579; - } - - public - void test_ctor_0arg() throws UnknownHostException { - AAAARecord ar = new AAAARecord(); - assertNull(ar.getName()); - assertEquals(0, ar.getType()); - assertEquals(0, ar.getDClass()); - assertEquals(0, ar.getTTL()); - assertNull(ar.getAddress()); - } - - public - void test_getObject() { - AAAARecord ar = new AAAARecord(); - DnsRecord r = ar.getObject(); - assertTrue(r instanceof AAAARecord); - } - - public - void test_ctor_4arg() { - AAAARecord ar = new AAAARecord(m_an, DnsClass.IN, m_ttl, m_addr); - assertEquals(m_an, ar.getName()); - assertEquals(DnsRecordType.AAAA, ar.getType()); - assertEquals(DnsClass.IN, ar.getDClass()); - assertEquals(m_ttl, ar.getTTL()); - assertEquals(m_addr, ar.getAddress()); - - // a relative name - try { - new AAAARecord(m_rn, DnsClass.IN, m_ttl, m_addr); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException e) { - } - - // an IPv4 address - try { - new AAAARecord(m_an, DnsClass.IN, m_ttl, InetAddress.getByName("192.168.0.1")); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } catch (UnknownHostException e) { - fail(e.getMessage()); - } - } - - public - void test_rrFromWire() throws IOException { - DnsInput di = new DnsInput(m_addr_bytes); - AAAARecord ar = new AAAARecord(); - - ar.rrFromWire(di); - - assertEquals(m_addr, ar.getAddress()); - } - - public - void test_rdataFromString() throws IOException { - Tokenizer t = new Tokenizer(m_addr_string); - AAAARecord ar = new AAAARecord(); - - ar.rdataFromString(t, null); - - assertEquals(m_addr, ar.getAddress()); - - // invalid address - t = new Tokenizer("193.160.232.1"); - ar = new AAAARecord(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_rrToString() { - AAAARecord ar = new AAAARecord(m_an, DnsClass.IN, m_ttl, m_addr); - StringBuilder sb = new StringBuilder(); - ar.rrToString(sb); - assertEquals(m_addr_string, sb.toString()); - } - - public - void test_rrToWire() { - AAAARecord ar = new AAAARecord(m_an, DnsClass.IN, m_ttl, m_addr); - - // canonical - DnsOutput dout = new DnsOutput(); - ar.rrToWire(dout, null, true); - assertTrue(Arrays.equals(m_addr_bytes, dout.toByteArray())); - - // case sensitive - dout = new DnsOutput(); - ar.rrToWire(dout, null, false); - assertTrue(Arrays.equals(m_addr_bytes, dout.toByteArray())); - } -} diff --git a/test/dorkbox/network/dns/records/AFSDBRecordTest.java b/test/dorkbox/network/dns/records/AFSDBRecordTest.java deleted file mode 100644 index 877c7923..00000000 --- a/test/dorkbox/network/dns/records/AFSDBRecordTest.java +++ /dev/null @@ -1,65 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class AFSDBRecordTest extends TestCase { - public - void test_getObject() { - AFSDBRecord d = new AFSDBRecord(); - DnsRecord r = d.getObject(); - assertTrue(r instanceof AFSDBRecord); - } - - public - void test_ctor_5arg() throws TextParseException { - Name n = Name.fromString("My.Name."); - Name m = Name.fromString("My.OtherName."); - - AFSDBRecord d = new AFSDBRecord(n, DnsClass.IN, 0xABCDEL, 0xF1, m); - assertEquals(n, d.getName()); - assertEquals(DnsRecordType.AFSDB, d.getType()); - assertEquals(DnsClass.IN, d.getDClass()); - assertEquals(0xABCDEL, d.getTTL()); - assertEquals(0xF1, d.getSubtype()); - assertEquals(m, d.getHost()); - } -} diff --git a/test/dorkbox/network/dns/records/APLRecordTest.java b/test/dorkbox/network/dns/records/APLRecordTest.java deleted file mode 100644 index abed8038..00000000 --- a/test/dorkbox/network/dns/records/APLRecordTest.java +++ /dev/null @@ -1,696 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.RelativeNameException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.network.dns.records.APLRecord.Element; -import dorkbox.network.dns.utils.Address; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -public -class APLRecordTest { - public static - class Test_Element_init extends TestCase { - InetAddress m_addr4; - InetAddress m_addr6; - - @Override - protected - void setUp() throws TextParseException, UnknownHostException { - m_addr4 = InetAddress.getByName("193.160.232.5"); - m_addr6 = InetAddress.getByName("2001:db8:85a3:8d3:1319:8a2e:370:7334"); - } - - public - void test_valid_IPv4() { - Element el = new Element(true, m_addr4, 16); - assertEquals(Address.IPv4, el.family); - assertEquals(true, el.negative); - assertEquals(m_addr4, el.address); - assertEquals(16, el.prefixLength); - } - - public - void test_invalid_IPv4() { - try { - new Element(true, m_addr4, 33); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_valid_IPv6() { - Element el = new Element(false, m_addr6, 74); - assertEquals(Address.IPv6, el.family); - assertEquals(false, el.negative); - assertEquals(m_addr6, el.address); - assertEquals(74, el.prefixLength); - } - - public - void test_invalid_IPv6() { - try { - new Element(true, m_addr6, 129); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - } - - - public static - class Test_init extends TestCase { - Name m_an, m_rn; - long m_ttl; - ArrayList m_elements; - InetAddress m_addr4; - String m_addr4_string; - byte[] m_addr4_bytes; - InetAddress m_addr6; - String m_addr6_string; - byte[] m_addr6_bytes; - - public - void test_0arg() throws UnknownHostException { - APLRecord ar = new APLRecord(); - assertNull(ar.getName()); - assertEquals(0, ar.getType()); - assertEquals(0, ar.getDClass()); - assertEquals(0, ar.getTTL()); - assertNull(ar.getElements()); - } - - public - void test_getObject() { - APLRecord ar = new APLRecord(); - DnsRecord r = ar.getObject(); - assertTrue(r instanceof APLRecord); - } @Override - protected - void setUp() throws TextParseException, UnknownHostException { - m_an = Name.fromString("My.Absolute.Name."); - m_rn = Name.fromString("My.Relative.Name"); - m_ttl = 0x13579; - m_addr4_string = "193.160.232.5"; - m_addr4 = InetAddress.getByName(m_addr4_string); - m_addr4_bytes = m_addr4.getAddress(); - - m_addr6_string = "2001:db8:85a3:8d3:1319:8a2e:370:7334"; - m_addr6 = InetAddress.getByName(m_addr6_string); - m_addr6_bytes = m_addr6.getAddress(); - - m_elements = new ArrayList(2); - Element e = new Element(true, m_addr4, 12); - m_elements.add(e); - - e = new Element(false, m_addr6, 64); - m_elements.add(e); - } - - public - void test_4arg_basic() { - APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, m_elements); - assertEquals(m_an, ar.getName()); - assertEquals(DnsRecordType.APL, ar.getType()); - assertEquals(DnsClass.IN, ar.getDClass()); - assertEquals(m_ttl, ar.getTTL()); - assertEquals(m_elements, ar.getElements()); - } - - public - void test_4arg_empty_elements() { - APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, new ArrayList()); - assertEquals(new ArrayList(), ar.getElements()); - } - - public - void test_4arg_relative_name() { - try { - new APLRecord(m_rn, DnsClass.IN, m_ttl, m_elements); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException e) { - } - } - - public - void test_4arg_invalid_elements() { - m_elements = new ArrayList(); - m_elements.add(new Object()); - try { - new APLRecord(m_an, DnsClass.IN, m_ttl, m_elements); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - - - - } - - - public static - class Test_rrFromWire extends TestCase { - InetAddress m_addr4; - byte[] m_addr4_bytes; - InetAddress m_addr6; - byte[] m_addr6_bytes; - - public - void test_validIPv4() throws IOException { - byte[] raw = new byte[] {0, 1, 8, (byte) 0x84, m_addr4_bytes[0], m_addr4_bytes[1], m_addr4_bytes[2], m_addr4_bytes[3]}; - - DnsInput di = new DnsInput(raw); - APLRecord ar = new APLRecord(); - ar.rrFromWire(di); - - ArrayList exp = new ArrayList(); - exp.add(new Element(true, m_addr4, 8)); - assertEquals(exp, ar.getElements()); - } - - public - void test_validIPv4_short_address() throws IOException { - byte[] raw = new byte[] {0, 1, 20, (byte) 0x83, m_addr4_bytes[0], m_addr4_bytes[1], m_addr4_bytes[2]}; - - DnsInput di = new DnsInput(raw); - APLRecord ar = new APLRecord(); - ar.rrFromWire(di); - - InetAddress a = InetAddress.getByName("193.160.232.0"); - - ArrayList exp = new ArrayList(); - exp.add(new Element(true, a, 20)); - assertEquals(exp, ar.getElements()); - } @Override - protected - void setUp() throws TextParseException, UnknownHostException { - m_addr4 = InetAddress.getByName("193.160.232.5"); - m_addr4_bytes = m_addr4.getAddress(); - - m_addr6 = InetAddress.getByName("2001:db8:85a3:8d3:1319:8a2e:370:7334"); - m_addr6_bytes = m_addr6.getAddress(); - } - - public - void test_invalid_IPv4_prefix() throws IOException { - byte[] raw = new byte[] {0, 1, 33, (byte) 0x84, m_addr4_bytes[0], m_addr4_bytes[1], m_addr4_bytes[2], m_addr4_bytes[3]}; - - DnsInput di = new DnsInput(raw); - APLRecord ar = new APLRecord(); - try { - ar.rrFromWire(di); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - } - } - - public - void test_invalid_IPv4_length() throws IOException { - byte[] raw = new byte[] {0, 1, 8, (byte) 0x85, m_addr4_bytes[0], m_addr4_bytes[1], m_addr4_bytes[2], m_addr4_bytes[3], 10}; - - DnsInput di = new DnsInput(raw); - APLRecord ar = new APLRecord(); - try { - ar.rrFromWire(di); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - } - } - - public - void test_multiple_validIPv4() throws IOException { - byte[] raw = new byte[] {0, 1, 8, (byte) 0x84, m_addr4_bytes[0], m_addr4_bytes[1], m_addr4_bytes[2], m_addr4_bytes[3], 0, 1, 30, - (byte) 0x4, m_addr4_bytes[0], m_addr4_bytes[1], m_addr4_bytes[2], m_addr4_bytes[3],}; - - DnsInput di = new DnsInput(raw); - APLRecord ar = new APLRecord(); - ar.rrFromWire(di); - - ArrayList exp = new ArrayList(); - exp.add(new Element(true, m_addr4, 8)); - exp.add(new Element(false, m_addr4, 30)); - assertEquals(exp, ar.getElements()); - } - - public - void test_validIPv6() throws IOException { - byte[] raw = new byte[] {0, 2, (byte) 115, (byte) 0x10, m_addr6_bytes[0], m_addr6_bytes[1], m_addr6_bytes[2], m_addr6_bytes[3], - m_addr6_bytes[4], m_addr6_bytes[5], m_addr6_bytes[6], m_addr6_bytes[7], m_addr6_bytes[8], - m_addr6_bytes[9], m_addr6_bytes[10], m_addr6_bytes[11], m_addr6_bytes[12], m_addr6_bytes[13], - m_addr6_bytes[14], m_addr6_bytes[15]}; - - DnsInput di = new DnsInput(raw); - APLRecord ar = new APLRecord(); - ar.rrFromWire(di); - - ArrayList exp = new ArrayList(); - exp.add(new Element(false, m_addr6, 115)); - assertEquals(exp, ar.getElements()); - } - - public - void test_valid_nonIP() throws IOException { - byte[] raw = new byte[] {0, 3, (byte) 130, (byte) 0x85, 1, 2, 3, 4, 5}; - - DnsInput di = new DnsInput(raw); - APLRecord ar = new APLRecord(); - ar.rrFromWire(di); - - List l = ar.getElements(); - assertEquals(1, l.size()); - - Element el = (Element) l.get(0); - assertEquals(3, el.family); - assertEquals(true, el.negative); - assertEquals(130, el.prefixLength); - assertTrue(Arrays.equals(new byte[] {1, 2, 3, 4, 5}, (byte[]) el.address)); - } - - - - - } - - - public static - class Test_rdataFromString extends TestCase { - InetAddress m_addr4; - String m_addr4_string; - byte[] m_addr4_bytes; - InetAddress m_addr6; - String m_addr6_string; - byte[] m_addr6_bytes; - - public - void test_validIPv4() throws IOException { - Tokenizer t = new Tokenizer("1:" + m_addr4_string + "/11\n"); - APLRecord ar = new APLRecord(); - ar.rdataFromString(t, null); - - ArrayList exp = new ArrayList(); - exp.add(new Element(false, m_addr4, 11)); - - assertEquals(exp, ar.getElements()); - - // make sure extra token is put back - assertEquals(Tokenizer.EOL, t.get().type); - } - - public - void test_valid_multi() throws IOException { - Tokenizer t = new Tokenizer("1:" + m_addr4_string + "/11 !2:" + m_addr6_string + "/100"); - APLRecord ar = new APLRecord(); - ar.rdataFromString(t, null); - - ArrayList exp = new ArrayList(); - exp.add(new Element(false, m_addr4, 11)); - exp.add(new Element(true, m_addr6, 100)); - - assertEquals(exp, ar.getElements()); - } @Override - protected - void setUp() throws TextParseException, UnknownHostException { - m_addr4_string = "193.160.232.5"; - m_addr4 = InetAddress.getByName(m_addr4_string); - m_addr4_bytes = m_addr4.getAddress(); - - m_addr6_string = "2001:db8:85a3:8d3:1319:8a2e:370:7334"; - m_addr6 = InetAddress.getByName(m_addr6_string); - m_addr6_bytes = m_addr6.getAddress(); - } - - public - void test_validIPv6() throws IOException { - Tokenizer t = new Tokenizer("!2:" + m_addr6_string + "/36\n"); - APLRecord ar = new APLRecord(); - ar.rdataFromString(t, null); - - ArrayList exp = new ArrayList(); - exp.add(new Element(true, m_addr6, 36)); - - assertEquals(exp, ar.getElements()); - - // make sure extra token is put back - assertEquals(Tokenizer.EOL, t.get().type); - } - - public - void test_no_colon() throws IOException { - Tokenizer t = new Tokenizer("!1192.68.0.1/20"); - APLRecord ar = new APLRecord(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_colon_and_slash_swapped() throws IOException { - Tokenizer t = new Tokenizer("!1/192.68.0.1:20"); - APLRecord ar = new APLRecord(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_no_slash() throws IOException { - Tokenizer t = new Tokenizer("!1:192.68.0.1|20"); - APLRecord ar = new APLRecord(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_empty_family() throws IOException { - Tokenizer t = new Tokenizer("!:192.68.0.1/20"); - APLRecord ar = new APLRecord(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_malformed_family() throws IOException { - Tokenizer t = new Tokenizer("family:192.68.0.1/20"); - APLRecord ar = new APLRecord(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_invalid_family() throws IOException { - Tokenizer t = new Tokenizer("3:192.68.0.1/20"); - APLRecord ar = new APLRecord(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_empty_prefix() throws IOException { - Tokenizer t = new Tokenizer("1:192.68.0.1/"); - APLRecord ar = new APLRecord(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_malformed_prefix() throws IOException { - Tokenizer t = new Tokenizer("1:192.68.0.1/prefix"); - APLRecord ar = new APLRecord(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_invalid_prefix() throws IOException { - Tokenizer t = new Tokenizer("1:192.68.0.1/33"); - APLRecord ar = new APLRecord(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_empty_address() throws IOException { - Tokenizer t = new Tokenizer("1:/33"); - APLRecord ar = new APLRecord(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_malformed_address() throws IOException { - Tokenizer t = new Tokenizer("1:A.B.C.D/33"); - APLRecord ar = new APLRecord(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - - - - } - - - public static - class Test_rrToString extends TestCase { - Name m_an, m_rn; - long m_ttl; - ArrayList m_elements; - InetAddress m_addr4; - String m_addr4_string; - byte[] m_addr4_bytes; - InetAddress m_addr6; - String m_addr6_string; - byte[] m_addr6_bytes; - - public - void test() { - APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, m_elements); - StringBuilder sb = new StringBuilder(); - ar.rrToString(sb); - assertEquals("!1:" + m_addr4_string + "/12 2:" + m_addr6_string + "/64", sb.toString()); - } - - @Override - protected - void setUp() throws TextParseException, UnknownHostException { - m_an = Name.fromString("My.Absolute.Name."); - m_rn = Name.fromString("My.Relative.Name"); - m_ttl = 0x13579; - m_addr4_string = "193.160.232.5"; - m_addr4 = InetAddress.getByName(m_addr4_string); - m_addr4_bytes = m_addr4.getAddress(); - - m_addr6_string = "2001:db8:85a3:8d3:1319:8a2e:370:7334"; - m_addr6 = InetAddress.getByName(m_addr6_string); - m_addr6_bytes = m_addr6.getAddress(); - - m_elements = new ArrayList(2); - Element e = new Element(true, m_addr4, 12); - m_elements.add(e); - - e = new Element(false, m_addr6, 64); - m_elements.add(e); - } - - - } - - - public static - class Test_rrToWire extends TestCase { - Name m_an, m_rn; - long m_ttl; - ArrayList m_elements; - InetAddress m_addr4; - String m_addr4_string; - byte[] m_addr4_bytes; - InetAddress m_addr6; - String m_addr6_string; - byte[] m_addr6_bytes; - - public - void test_empty() { - APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, new ArrayList()); - DnsOutput dout = new DnsOutput(); - - ar.rrToWire(dout, null, true); - assertTrue(Arrays.equals(new byte[0], dout.toByteArray())); - } - - public - void test_basic() { - APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, m_elements); - - byte[] exp = new byte[] {0, 1, 12, (byte) 0x84, m_addr4_bytes[0], m_addr4_bytes[1], m_addr4_bytes[2], m_addr4_bytes[3], 0, 2, - 64, 0x10, m_addr6_bytes[0], m_addr6_bytes[1], m_addr6_bytes[2], m_addr6_bytes[3], m_addr6_bytes[4], - m_addr6_bytes[5], m_addr6_bytes[6], m_addr6_bytes[7], m_addr6_bytes[8], m_addr6_bytes[9], - m_addr6_bytes[10], m_addr6_bytes[11], m_addr6_bytes[12], m_addr6_bytes[13], m_addr6_bytes[14], - m_addr6_bytes[15]}; - - DnsOutput dout = new DnsOutput(); - - ar.rrToWire(dout, null, true); - assertTrue(Arrays.equals(exp, dout.toByteArray())); - } @Override - protected - void setUp() throws TextParseException, UnknownHostException { - m_an = Name.fromString("My.Absolute.Name."); - m_rn = Name.fromString("My.Relative.Name"); - m_ttl = 0x13579; - m_addr4_string = "193.160.232.5"; - m_addr4 = InetAddress.getByName(m_addr4_string); - m_addr4_bytes = m_addr4.getAddress(); - - m_addr6_string = "2001:db8:85a3:8d3:1319:8a2e:370:7334"; - m_addr6 = InetAddress.getByName(m_addr6_string); - m_addr6_bytes = m_addr6.getAddress(); - - m_elements = new ArrayList(2); - Element e = new Element(true, m_addr4, 12); - m_elements.add(e); - - e = new Element(false, m_addr6, 64); - m_elements.add(e); - } - - public - void test_non_IP() throws IOException { - byte[] exp = new byte[] {0, 3, (byte) 130, (byte) 0x85, 1, 2, 3, 4, 5}; - - DnsInput di = new DnsInput(exp); - APLRecord ar = new APLRecord(); - ar.rrFromWire(di); - - DnsOutput dout = new DnsOutput(); - - ar.rrToWire(dout, null, true); - assertTrue(Arrays.equals(exp, dout.toByteArray())); - } - - public - void test_address_with_embedded_zero() throws UnknownHostException { - InetAddress a = InetAddress.getByName("232.0.11.1"); - ArrayList elements = new ArrayList(); - elements.add(new Element(true, a, 31)); - - APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, elements); - - byte[] exp = new byte[] {0, 1, 31, (byte) 0x84, (byte) 232, 0, 11, 1}; - - DnsOutput dout = new DnsOutput(); - - ar.rrToWire(dout, null, true); - assertTrue(Arrays.equals(exp, dout.toByteArray())); - } - - public - void test_short_address() throws UnknownHostException { - InetAddress a = InetAddress.getByName("232.0.11.0"); - ArrayList elements = new ArrayList(); - elements.add(new Element(true, a, 31)); - - APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, elements); - - byte[] exp = new byte[] {0, 1, 31, (byte) 0x83, (byte) 232, 0, 11}; - - DnsOutput dout = new DnsOutput(); - - ar.rrToWire(dout, null, true); - assertTrue(Arrays.equals(exp, dout.toByteArray())); - } - - public - void test_wildcard_address() throws UnknownHostException { - InetAddress a = InetAddress.getByName("0.0.0.0"); - ArrayList elements = new ArrayList(); - elements.add(new Element(true, a, 31)); - - APLRecord ar = new APLRecord(m_an, DnsClass.IN, m_ttl, elements); - - byte[] exp = new byte[] {0, 1, 31, (byte) 0x80}; - - DnsOutput dout = new DnsOutput(); - - ar.rrToWire(dout, null, true); - assertTrue(Arrays.equals(exp, dout.toByteArray())); - } - - - - - } - - public static - Test suite() { - TestSuite s = new TestSuite(); - s.addTestSuite(Test_Element_init.class); - s.addTestSuite(Test_init.class); - s.addTestSuite(Test_rrFromWire.class); - s.addTestSuite(Test_rdataFromString.class); - s.addTestSuite(Test_rrToString.class); - s.addTestSuite(Test_rrToWire.class); - return s; - } -} diff --git a/test/dorkbox/network/dns/records/ARecordTest.java b/test/dorkbox/network/dns/records/ARecordTest.java deleted file mode 100644 index 711c8e67..00000000 --- a/test/dorkbox/network/dns/records/ARecordTest.java +++ /dev/null @@ -1,163 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.RelativeNameException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.TestCase; - -public -class ARecordTest extends TestCase { - Name m_an, m_rn; - InetAddress m_addr; - String m_addr_string; - byte[] m_addr_bytes; - long m_ttl; - - @Override - protected - void setUp() throws TextParseException, UnknownHostException { - m_an = Name.fromString("My.Absolute.Name."); - m_rn = Name.fromString("My.Relative.Name"); - m_addr_string = "193.160.232.5"; - m_addr = InetAddress.getByName(m_addr_string); - m_addr_bytes = m_addr.getAddress(); - m_ttl = 0x13579; - } - - public - void test_ctor_0arg() throws UnknownHostException { - ARecord ar = new ARecord(); - assertNull(ar.getName()); - assertEquals(0, ar.getType()); - assertEquals(0, ar.getDClass()); - assertEquals(0, ar.getTTL()); - assertEquals(InetAddress.getByName("0.0.0.0"), ar.getAddress()); - } - - public - void test_getObject() { - ARecord ar = new ARecord(); - DnsRecord r = ar.getObject(); - assertTrue(r instanceof ARecord); - } - - public - void test_ctor_4arg() { - ARecord ar = new ARecord(m_an, DnsClass.IN, m_ttl, m_addr); - assertEquals(m_an, ar.getName()); - assertEquals(DnsRecordType.A, ar.getType()); - assertEquals(DnsClass.IN, ar.getDClass()); - assertEquals(m_ttl, ar.getTTL()); - assertEquals(m_addr, ar.getAddress()); - - // a relative name - try { - new ARecord(m_rn, DnsClass.IN, m_ttl, m_addr); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException e) { - } - - // an IPv6 address - try { - new ARecord(m_an, DnsClass.IN, m_ttl, InetAddress.getByName("2001:0db8:85a3:08d3:1319:8a2e:0370:7334")); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } catch (UnknownHostException e) { - fail(e.getMessage()); - } - } - - public - void test_rrFromWire() throws IOException { - DnsInput di = new DnsInput(m_addr_bytes); - ARecord ar = new ARecord(); - - ar.rrFromWire(di); - - assertEquals(m_addr, ar.getAddress()); - } - - public - void test_rdataFromString() throws IOException { - Tokenizer t = new Tokenizer(m_addr_string); - ARecord ar = new ARecord(); - - ar.rdataFromString(t, null); - - assertEquals(m_addr, ar.getAddress()); - - // invalid address - t = new Tokenizer("193.160.232"); - ar = new ARecord(); - try { - ar.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_rrToString() { - ARecord ar = new ARecord(m_an, DnsClass.IN, m_ttl, m_addr); - StringBuilder sb = new StringBuilder(); - ar.rrToString(sb); - assertEquals(m_addr_string, sb.toString()); - } - - public - void test_rrToWire() { - ARecord ar = new ARecord(m_an, DnsClass.IN, m_ttl, m_addr); - DnsOutput dout = new DnsOutput(); - - ar.rrToWire(dout, null, true); - assertTrue(Arrays.equals(m_addr_bytes, dout.toByteArray())); - - dout = new DnsOutput(); - ar.rrToWire(dout, null, false); - assertTrue(Arrays.equals(m_addr_bytes, dout.toByteArray())); - } -} diff --git a/test/dorkbox/network/dns/records/CNAMERecordTest.java b/test/dorkbox/network/dns/records/CNAMERecordTest.java deleted file mode 100644 index 06147975..00000000 --- a/test/dorkbox/network/dns/records/CNAMERecordTest.java +++ /dev/null @@ -1,73 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class CNAMERecordTest extends TestCase { - public - void test_ctor_0arg() { - CNAMERecord d = new CNAMERecord(); - assertNull(d.getName()); - assertNull(d.getTarget()); - assertNull(d.getAlias()); - } - - public - void test_ctor_4arg() throws TextParseException { - Name n = Name.fromString("my.name."); - Name a = Name.fromString("my.alias."); - - CNAMERecord d = new CNAMERecord(n, DnsClass.IN, 0xABCDEL, a); - assertEquals(n, d.getName()); - assertEquals(DnsRecordType.CNAME, d.getType()); - assertEquals(DnsClass.IN, d.getDClass()); - assertEquals(0xABCDEL, d.getTTL()); - assertEquals(a, d.getTarget()); - assertEquals(a, d.getAlias()); - } - - public - void test_getObject() { - CNAMERecord d = new CNAMERecord(); - DnsRecord r = d.getObject(); - assertTrue(r instanceof CNAMERecord); - } -} diff --git a/test/dorkbox/network/dns/records/DNAMERecordTest.java b/test/dorkbox/network/dns/records/DNAMERecordTest.java deleted file mode 100644 index 41de4ab1..00000000 --- a/test/dorkbox/network/dns/records/DNAMERecordTest.java +++ /dev/null @@ -1,73 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class DNAMERecordTest extends TestCase { - public - void test_ctor_0arg() { - DNAMERecord d = new DNAMERecord(); - assertNull(d.getName()); - assertNull(d.getTarget()); - assertNull(d.getAlias()); - } - - public - void test_ctor_4arg() throws TextParseException { - Name n = Name.fromString("my.name."); - Name a = Name.fromString("my.alias."); - - DNAMERecord d = new DNAMERecord(n, DnsClass.IN, 0xABCDEL, a); - assertEquals(n, d.getName()); - assertEquals(DnsRecordType.DNAME, d.getType()); - assertEquals(DnsClass.IN, d.getDClass()); - assertEquals(0xABCDEL, d.getTTL()); - assertEquals(a, d.getTarget()); - assertEquals(a, d.getAlias()); - } - - public - void test_getObject() { - DNAMERecord d = new DNAMERecord(); - DnsRecord r = d.getObject(); - assertTrue(r instanceof DNAMERecord); - } -} diff --git a/test/dorkbox/network/dns/records/DNSKEYRecordTest.java b/test/dorkbox/network/dns/records/DNSKEYRecordTest.java deleted file mode 100644 index 8406d75f..00000000 --- a/test/dorkbox/network/dns/records/DNSKEYRecordTest.java +++ /dev/null @@ -1,116 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.UnknownHostException; -import java.util.Arrays; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.RelativeNameException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.TestCase; - -public -class DNSKEYRecordTest extends TestCase { - public - void test_ctor_0arg() throws UnknownHostException { - DNSKEYRecord ar = new DNSKEYRecord(); - assertNull(ar.getName()); - assertEquals(0, ar.getType()); - assertEquals(0, ar.getDClass()); - assertEquals(0, ar.getTTL()); - assertEquals(0, ar.getAlgorithm()); - assertEquals(0, ar.getFlags()); - assertEquals(0, ar.getFootprint()); - assertEquals(0, ar.getProtocol()); - assertNull(ar.getKey()); - } - - public - void test_getObject() { - DNSKEYRecord ar = new DNSKEYRecord(); - DnsRecord r = ar.getObject(); - assertTrue(r instanceof DNSKEYRecord); - } - - public - void test_ctor_7arg() throws TextParseException { - Name n = Name.fromString("My.Absolute.Name."); - Name r = Name.fromString("My.Relative.Name"); - byte[] key = new byte[] {0, 1, 3, 5, 7, 9}; - - DNSKEYRecord kr = new DNSKEYRecord(n, DnsClass.IN, 0x24AC, 0x9832, 0x12, 0x67, key); - assertEquals(n, kr.getName()); - assertEquals(DnsRecordType.DNSKEY, kr.getType()); - assertEquals(DnsClass.IN, kr.getDClass()); - assertEquals(0x24AC, kr.getTTL()); - assertEquals(0x9832, kr.getFlags()); - assertEquals(0x12, kr.getProtocol()); - assertEquals(0x67, kr.getAlgorithm()); - assertTrue(Arrays.equals(key, kr.getKey())); - - // a relative name - try { - new DNSKEYRecord(r, DnsClass.IN, 0x24AC, 0x9832, 0x12, 0x67, key); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException e) { - } - } - - public - void test_rdataFromString() throws IOException, TextParseException { - // basic - DNSKEYRecord kr = new DNSKEYRecord(); - Tokenizer st = new Tokenizer(0xABCD + " " + 0x81 + " RSASHA1 AQIDBAUGBwgJ"); - kr.rdataFromString(st, null); - assertEquals(0xABCD, kr.getFlags()); - assertEquals(0x81, kr.getProtocol()); - assertEquals(DNSSEC.Algorithm.RSASHA1, kr.getAlgorithm()); - assertTrue(Arrays.equals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}, kr.getKey())); - - // invalid algorithm - kr = new DNSKEYRecord(); - st = new Tokenizer(0x1212 + " " + 0xAA + " ZONE AQIDBAUGBwgJ"); - try { - kr.rdataFromString(st, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } -} diff --git a/test/dorkbox/network/dns/records/DNSOutputTest.java b/test/dorkbox/network/dns/records/DNSOutputTest.java deleted file mode 100644 index 2628f536..00000000 --- a/test/dorkbox/network/dns/records/DNSOutputTest.java +++ /dev/null @@ -1,263 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.DnsOutput; -import junit.framework.TestCase; - -public -class DNSOutputTest extends TestCase { - private DnsOutput m_do; - - @Override - public - void setUp() { - m_do = new DnsOutput(1); - } - - public - void test_default_ctor() { - m_do = new DnsOutput(); - assertEquals(0, m_do.current()); - } - - public - void test_initial_state() { - assertEquals(0, m_do.current()); - try { - m_do.restore(); - fail("IllegalStateException not thrown"); - } catch (IllegalStateException e) { - // pass - } - try { - m_do.jump(1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - // pass - } - } - - public - void test_writeU8_basic() { - m_do.writeU8(1); - assertEquals(1, m_do.current()); - - byte[] curr = m_do.toByteArray(); - assertEquals(1, curr.length); - assertEquals(1, curr[0]); - } - - public - void test_writeU8_expand() { - // starts off at 1; - m_do.writeU8(1); - m_do.writeU8(2); - - assertEquals(2, m_do.current()); - - byte[] curr = m_do.toByteArray(); - assertEquals(2, curr.length); - assertEquals(1, curr[0]); - assertEquals(2, curr[1]); - } - - public - void test_writeU8_max() { - m_do.writeU8(0xFF); - byte[] curr = m_do.toByteArray(); - assertEquals((byte) 0xFF, (byte) curr[0]); - } - - public - void test_writeU8_toobig() { - try { - m_do.writeU8(0x1FF); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - // pass - } - } - - public - void test_writeU16_basic() { - m_do.writeU16(0x100); - assertEquals(2, m_do.current()); - - byte[] curr = m_do.toByteArray(); - assertEquals(2, curr.length); - assertEquals(1, curr[0]); - assertEquals(0, curr[1]); - } - - public - void test_writeU16_max() { - m_do.writeU16(0xFFFF); - byte[] curr = m_do.toByteArray(); - assertEquals((byte) 0xFF, (byte) curr[0]); - assertEquals((byte) 0XFF, (byte) curr[1]); - } - - public - void test_writeU16_toobig() { - try { - m_do.writeU16(0x1FFFF); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - // pass - } - } - - public - void test_writeU32_basic() { - m_do.writeU32(0x11001011); - assertEquals(4, m_do.current()); - - byte[] curr = m_do.toByteArray(); - assertEquals(4, curr.length); - assertEquals(0x11, curr[0]); - assertEquals(0x00, curr[1]); - assertEquals(0x10, curr[2]); - assertEquals(0x11, curr[3]); - } - - public - void test_writeU32_max() { - m_do.writeU32(0xFFFFFFFFL); - byte[] curr = m_do.toByteArray(); - assertEquals((byte) 0xFF, (byte) curr[0]); - assertEquals((byte) 0XFF, (byte) curr[1]); - assertEquals((byte) 0XFF, (byte) curr[2]); - assertEquals((byte) 0XFF, (byte) curr[3]); - } - - public - void test_writeU32_toobig() { - try { - m_do.writeU32(0x1FFFFFFFFL); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - // pass - } - } - - public - void test_jump_basic() { - m_do.writeU32(0x11223344L); - assertEquals(4, m_do.current()); - m_do.jump(2); - assertEquals(2, m_do.current()); - m_do.writeU8(0x99); - byte[] curr = m_do.toByteArray(); - assertEquals(3, curr.length); - assertEquals(0x11, curr[0]); - assertEquals(0x22, curr[1]); - assertEquals((byte) 0x99, (byte) curr[2]); - - } - - public - void test_writeByteArray_1arg() { - byte[] in = new byte[] {(byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x12, (byte) 0x34}; - m_do.writeByteArray(in); - assertEquals(5, m_do.current()); - byte[] curr = m_do.toByteArray(); - assertEquals(in, curr); - } - - private - void assertEquals(byte[] exp, byte[] act) { - assertTrue(java.util.Arrays.equals(exp, act)); - } - - public - void test_writeByteArray_3arg() { - byte[] in = new byte[] {(byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x12, (byte) 0x34}; - m_do.writeByteArray(in, 2, 3); - assertEquals(3, m_do.current()); - byte[] exp = new byte[] {in[2], in[3], in[4]}; - byte[] curr = m_do.toByteArray(); - assertEquals(exp, curr); - } - - public - void test_writeCountedString_basic() { - byte[] in = new byte[] {'h', 'e', 'l', 'L', '0'}; - m_do.writeCountedString(in); - assertEquals(in.length + 1, m_do.current()); - byte[] curr = m_do.toByteArray(); - byte[] exp = new byte[] {(byte) (in.length), in[0], in[1], in[2], in[3], in[4]}; - assertEquals(exp, curr); - } - - public - void test_writeCountedString_empty() { - byte[] in = new byte[] {}; - m_do.writeCountedString(in); - assertEquals(in.length + 1, m_do.current()); - byte[] curr = m_do.toByteArray(); - byte[] exp = new byte[] {(byte) (in.length)}; - assertEquals(exp, curr); - } - - public - void test_writeCountedString_toobig() { - byte[] in = new byte[256]; - try { - m_do.writeCountedString(in); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - // pass - } - } - - public - void test_save_restore() { - m_do.writeU32(0x12345678L); - assertEquals(4, m_do.current()); - m_do.save(); - m_do.writeU16(0xABCD); - assertEquals(6, m_do.current()); - m_do.restore(); - assertEquals(4, m_do.current()); - try { - m_do.restore(); - fail("IllegalArgumentException not thrown"); - } catch (IllegalStateException e) { - // pass - } - } - -} diff --git a/test/dorkbox/network/dns/records/DNSSECSIG0Test.java b/test/dorkbox/network/dns/records/DNSSECSIG0Test.java deleted file mode 100644 index 248c133d..00000000 --- a/test/dorkbox/network/dns/records/DNSSECSIG0Test.java +++ /dev/null @@ -1,55 +0,0 @@ -package dorkbox.network.dns.records; - -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.PrivateKey; -import java.security.PublicKey; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import junit.framework.TestCase; - -public -class DNSSECSIG0Test extends TestCase { - - private static final String SIGNATURE_ALGORITHM = "SHA1withRSA"; - private static final String KEY_ALGORITHM = "RSA"; - int algorithm = DNSSEC.Algorithm.RSASHA1; - byte[] toSign = "The quick brown fox jumped over the lazy dog.".getBytes(); - - @Override - public - void setUp() { - } - - @Override - public - void tearDown() { - } - - public - void testSIG0() throws Exception { - Name sig0zoneName = new Name("sig0.invalid."); - Name sig0hostName = new Name("sometext.sig0.invalid."); - - KeyPairGenerator rsagen = KeyPairGenerator.getInstance("RSA"); - KeyPair rsapair = rsagen.generateKeyPair(); - PrivateKey privKey = rsapair.getPrivate(); - PublicKey pubKey = rsapair.getPublic(); - - KEYRecord keyRecord = new KEYRecord(sig0zoneName, - DnsClass.IN, - 0, - KEYRecord.Flags.HOST, - KEYRecord.Protocol.DNSSEC, - DNSSEC.Algorithm.RSASHA1, - pubKey); - TXTRecord txtRecord = new TXTRecord(sig0hostName, DnsClass.IN, 0, "Hello World!"); - Update updateMessage = new Update(sig0zoneName); - updateMessage.add(txtRecord); - - SIG0.signMessage(updateMessage, keyRecord, privKey, null); - DnsMessage message = new DnsMessage(updateMessage.toWire()); - SIG0.verifyMessage(message, message.toWire(), keyRecord, null); - } -} diff --git a/test/dorkbox/network/dns/records/DNSSECWithProviderTest.java b/test/dorkbox/network/dns/records/DNSSECWithProviderTest.java deleted file mode 100644 index ab7d9642..00000000 --- a/test/dorkbox/network/dns/records/DNSSECWithProviderTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package dorkbox.network.dns.records; - -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.Signature; - -import junit.framework.TestCase; - - -public -class DNSSECWithProviderTest extends TestCase { - - private static final String SIGNATURE_ALGORITHM = "SHA1withRSA"; - private static final String KEY_ALGORITHM = "RSA"; - int algorithm = DNSSEC.Algorithm.RSASHA1; - byte[] toSign = "The quick brown fox jumped over the lazy dog.".getBytes(); - - @Override - public - void setUp() { - } - - @Override - public - void tearDown() { - } - - public - void testSignSoftware() throws Exception { - - KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM); - keyPairGenerator.initialize(512); - KeyPair keyPair = keyPairGenerator.generateKeyPair(); - - Signature signer = Signature.getInstance(SIGNATURE_ALGORITHM); - signer.initSign(keyPair.getPrivate()); - signer.update(toSign); - byte[] signature = signer.sign(); - assertNotNull(signature); - - // verify the signature - Signature verifier = Signature.getInstance(SIGNATURE_ALGORITHM); - verifier.initVerify(keyPair.getPublic()); - verifier.update(toSign); - boolean verify = verifier.verify(signature); - assertTrue(verify); - - } -} diff --git a/test/dorkbox/network/dns/records/DSRecordTest.java b/test/dorkbox/network/dns/records/DSRecordTest.java deleted file mode 100644 index c155214f..00000000 --- a/test/dorkbox/network/dns/records/DSRecordTest.java +++ /dev/null @@ -1,243 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.util.Arrays; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -public -class DSRecordTest extends TestCase { - public - void test_ctor_0arg() { - DSRecord dr = new DSRecord(); - assertNull(dr.getName()); - assertEquals(0, dr.getType()); - assertEquals(0, dr.getDClass()); - assertEquals(0, dr.getTTL()); - assertEquals(0, dr.getAlgorithm()); - assertEquals(0, dr.getDigestID()); - assertNull(dr.getDigest()); - assertEquals(0, dr.getFootprint()); - } - - public - void test_getObject() { - DSRecord dr = new DSRecord(); - DnsRecord r = dr.getObject(); - assertTrue(r instanceof DSRecord); - } - - public static - class Test_Ctor_7arg extends TestCase { - private Name m_n; - private long m_ttl; - private int m_footprint; - private int m_algorithm; - private int m_digestid; - private byte[] m_digest; - - @Override - protected - void setUp() throws TextParseException { - m_n = Name.fromString("The.Name."); - m_ttl = 0xABCDL; - m_footprint = 0xEF01; - m_algorithm = 0x23; - m_digestid = 0x45; - m_digest = new byte[] {(byte) 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF}; - } - - public - void test_basic() throws TextParseException { - DSRecord dr = new DSRecord(m_n, DnsClass.IN, m_ttl, m_footprint, m_algorithm, m_digestid, m_digest); - assertEquals(m_n, dr.getName()); - assertEquals(DnsClass.IN, dr.getDClass()); - assertEquals(DnsRecordType.DS, dr.getType()); - assertEquals(m_ttl, dr.getTTL()); - assertEquals(m_footprint, dr.getFootprint()); - assertEquals(m_algorithm, dr.getAlgorithm()); - assertEquals(m_digestid, dr.getDigestID()); - assertTrue(Arrays.equals(m_digest, dr.getDigest())); - } - - public - void test_toosmall_footprint() throws TextParseException { - try { - new DSRecord(m_n, DnsClass.IN, m_ttl, -1, m_algorithm, m_digestid, m_digest); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_toobig_footprint() throws TextParseException { - try { - new DSRecord(m_n, DnsClass.IN, m_ttl, 0x10000, m_algorithm, m_digestid, m_digest); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_toosmall_algorithm() throws TextParseException { - try { - new DSRecord(m_n, DnsClass.IN, m_ttl, m_footprint, -1, m_digestid, m_digest); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_toobig_algorithm() throws TextParseException { - try { - new DSRecord(m_n, DnsClass.IN, m_ttl, m_footprint, 0x10000, m_digestid, m_digest); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_toosmall_digestid() throws TextParseException { - try { - new DSRecord(m_n, DnsClass.IN, m_ttl, m_footprint, m_algorithm, -1, m_digest); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_toobig_digestid() throws TextParseException { - try { - new DSRecord(m_n, DnsClass.IN, m_ttl, m_footprint, m_algorithm, 0x10000, m_digest); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_null_digest() { - DSRecord dr = new DSRecord(m_n, DnsClass.IN, m_ttl, m_footprint, m_algorithm, m_digestid, null); - assertEquals(m_n, dr.getName()); - assertEquals(DnsClass.IN, dr.getDClass()); - assertEquals(DnsRecordType.DS, dr.getType()); - assertEquals(m_ttl, dr.getTTL()); - assertEquals(m_footprint, dr.getFootprint()); - assertEquals(m_algorithm, dr.getAlgorithm()); - assertEquals(m_digestid, dr.getDigestID()); - assertNull(dr.getDigest()); - } - } - - public - void test_rrFromWire() throws IOException { - byte[] raw = new byte[] {(byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x01, (byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89}; - DnsInput in = new DnsInput(raw); - - DSRecord dr = new DSRecord(); - dr.rrFromWire(in); - assertEquals(0xABCD, dr.getFootprint()); - assertEquals(0xEF, dr.getAlgorithm()); - assertEquals(0x01, dr.getDigestID()); - assertTrue(Arrays.equals(new byte[] {(byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89}, dr.getDigest())); - } - - public - void test_rdataFromString() throws IOException { - byte[] raw = new byte[] {(byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x01, (byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89}; - Tokenizer t = new Tokenizer(0xABCD + " " + 0xEF + " " + 0x01 + " 23456789AB"); - - DSRecord dr = new DSRecord(); - dr.rdataFromString(t, null); - assertEquals(0xABCD, dr.getFootprint()); - assertEquals(0xEF, dr.getAlgorithm()); - assertEquals(0x01, dr.getDigestID()); - assertTrue(Arrays.equals(new byte[] {(byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89, (byte) 0xAB}, dr.getDigest())); - } - - public - void test_rrToString() throws TextParseException { - String exp = 0xABCD + " " + 0xEF + " " + 0x01 + " 23456789AB"; - - DSRecord dr = new DSRecord(Name.fromString("The.Name."), - DnsClass.IN, - 0x123, - 0xABCD, - 0xEF, - 0x01, - new byte[] {(byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89, (byte) 0xAB}); - - StringBuilder sb = new StringBuilder(); - dr.rrToString(sb); - assertEquals(exp, sb.toString()); - } - - public - void test_rrToWire() throws TextParseException { - DSRecord dr = new DSRecord(Name.fromString("The.Name."), - DnsClass.IN, - 0x123, - 0xABCD, - 0xEF, - 0x01, - new byte[] {(byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89, (byte) 0xAB}); - - byte[] exp = new byte[] {(byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x01, (byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89, - (byte) 0xAB}; - - DnsOutput out = new DnsOutput(); - dr.rrToWire(out, null, true); - - assertTrue(Arrays.equals(exp, out.toByteArray())); - } - - public static - Test suite() { - TestSuite s = new TestSuite(); - s.addTestSuite(Test_Ctor_7arg.class); - s.addTestSuite(DSRecordTest.class); - return s; - } -} diff --git a/test/dorkbox/network/dns/records/EmptyRecordTest.java b/test/dorkbox/network/dns/records/EmptyRecordTest.java deleted file mode 100644 index 627d3606..00000000 --- a/test/dorkbox/network/dns/records/EmptyRecordTest.java +++ /dev/null @@ -1,105 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.UnknownHostException; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.TestCase; - -public -class EmptyRecordTest extends TestCase { - public - void test_ctor() throws UnknownHostException { - EmptyRecord ar = new EmptyRecord(); - assertNull(ar.getName()); - assertEquals(0, ar.getType()); - assertEquals(0, ar.getDClass()); - assertEquals(0, ar.getTTL()); - } - - public - void test_getObject() { - EmptyRecord ar = new EmptyRecord(); - DnsRecord r = ar.getObject(); - assertTrue(r instanceof EmptyRecord); - } - - public - void test_rrFromWire() throws IOException { - DnsInput i = new DnsInput(new byte[] {1, 2, 3, 4, 5}); - i.jump(3); - - EmptyRecord er = new EmptyRecord(); - er.rrFromWire(i); - assertEquals(3, i.readIndex()); - assertNull(er.getName()); - assertEquals(0, er.getType()); - assertEquals(0, er.getDClass()); - assertEquals(0, er.getTTL()); - } - - public - void test_rdataFromString() throws IOException { - Tokenizer t = new Tokenizer("these are the tokens"); - EmptyRecord er = new EmptyRecord(); - er.rdataFromString(t, null); - assertNull(er.getName()); - assertEquals(0, er.getType()); - assertEquals(0, er.getDClass()); - assertEquals(0, er.getTTL()); - - assertEquals("these", t.getString()); - } - - public - void test_rrToString() { - EmptyRecord er = new EmptyRecord(); - StringBuilder sb = new StringBuilder(); - er.rrToString(sb); - assertEquals("", sb.toString()); - } - - public - void test_rrToWire() { - EmptyRecord er = new EmptyRecord(); - DnsOutput out = new DnsOutput(); - er.rrToWire(out, null, true); - assertEquals(0, out.toByteArray().length); - } -} diff --git a/test/dorkbox/network/dns/records/GPOSRecordTest.java b/test/dorkbox/network/dns/records/GPOSRecordTest.java deleted file mode 100644 index f4c36347..00000000 --- a/test/dorkbox/network/dns/records/GPOSRecordTest.java +++ /dev/null @@ -1,401 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.exceptions.WireParseException; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -public -class GPOSRecordTest extends TestCase { - public - void test_ctor_0arg() { - GPOSRecord gr = new GPOSRecord(); - assertNull(gr.getName()); - assertEquals(0, gr.getType()); - assertEquals(0, gr.getDClass()); - assertEquals(0, gr.getTTL()); - } - - public - void test_getObject() { - GPOSRecord gr = new GPOSRecord(); - DnsRecord r = gr.getObject(); - assertTrue(r instanceof GPOSRecord); - } - - public static - class Test_Ctor_6arg_doubles extends TestCase { - private Name m_n; - private long m_ttl; - private double m_lat, m_long, m_alt; - - @Override - protected - void setUp() throws TextParseException { - m_n = Name.fromString("The.Name."); - m_ttl = 0xABCDL; - m_lat = -10.43; - m_long = 76.12; - m_alt = 100.101; - } - - public - void test_basic() throws TextParseException { - GPOSRecord gr = new GPOSRecord(m_n, DnsClass.IN, m_ttl, m_long, m_lat, m_alt); - assertEquals(m_n, gr.getName()); - assertEquals(DnsClass.IN, gr.getDClass()); - assertEquals(DnsRecordType.GPOS, gr.getType()); - assertEquals(m_ttl, gr.getTTL()); - assertEquals(new Double(m_long), new Double(gr.getLongitude())); - assertEquals(new Double(m_lat), new Double(gr.getLatitude())); - assertEquals(new Double(m_alt), new Double(gr.getAltitude())); - assertEquals(new Double(m_long).toString(), gr.getLongitudeString()); - assertEquals(new Double(m_lat).toString(), gr.getLatitudeString()); - assertEquals(new Double(m_alt).toString(), gr.getAltitudeString()); - } - - public - void test_toosmall_longitude() throws TextParseException { - try { - new GPOSRecord(m_n, DnsClass.IN, m_ttl, -90.001, m_lat, m_alt); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_toobig_longitude() throws TextParseException { - try { - new GPOSRecord(m_n, DnsClass.IN, m_ttl, 90.001, m_lat, m_alt); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_toosmall_latitude() throws TextParseException { - try { - new GPOSRecord(m_n, DnsClass.IN, m_ttl, m_long, -180.001, m_alt); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_toobig_latitude() throws TextParseException { - try { - new GPOSRecord(m_n, DnsClass.IN, m_ttl, m_long, 180.001, m_alt); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_invalid_string() { - try { - new GPOSRecord(m_n, DnsClass.IN, m_ttl, new Double(m_long).toString(), "120.\\00ABC", new Double(m_alt).toString()); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - } - - - public static - class Test_Ctor_6arg_Strings extends TestCase { - private Name m_n; - private long m_ttl; - private double m_lat, m_long, m_alt; - - public - void test_basic() throws TextParseException { - GPOSRecord gr = new GPOSRecord(m_n, - DnsClass.IN, - m_ttl, - new Double(m_long).toString(), - new Double(m_lat).toString(), - new Double(m_alt).toString()); - assertEquals(m_n, gr.getName()); - assertEquals(DnsClass.IN, gr.getDClass()); - assertEquals(DnsRecordType.GPOS, gr.getType()); - assertEquals(m_ttl, gr.getTTL()); - assertEquals(new Double(m_long), new Double(gr.getLongitude())); - assertEquals(new Double(m_lat), new Double(gr.getLatitude())); - assertEquals(new Double(m_alt), new Double(gr.getAltitude())); - assertEquals(new Double(m_long).toString(), gr.getLongitudeString()); - assertEquals(new Double(m_lat).toString(), gr.getLatitudeString()); - assertEquals(new Double(m_alt).toString(), gr.getAltitudeString()); - } - - public - void test_toosmall_longitude() throws TextParseException { - try { - new GPOSRecord(m_n, DnsClass.IN, m_ttl, "-90.001", new Double(m_lat).toString(), new Double(m_alt).toString()); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } @Override - protected - void setUp() throws TextParseException { - m_n = Name.fromString("The.Name."); - m_ttl = 0xABCDL; - m_lat = -10.43; - m_long = 76.12; - m_alt = 100.101; - } - - public - void test_toobig_longitude() throws TextParseException { - try { - new GPOSRecord(m_n, DnsClass.IN, m_ttl, "90.001", new Double(m_lat).toString(), new Double(m_alt).toString()); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_toosmall_latitude() throws TextParseException { - try { - new GPOSRecord(m_n, DnsClass.IN, m_ttl, new Double(m_long).toString(), "-180.001", new Double(m_alt).toString()); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_toobig_latitude() throws TextParseException { - try { - new GPOSRecord(m_n, DnsClass.IN, m_ttl, new Double(m_long).toString(), "180.001", new Double(m_alt).toString()); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - - - - } - - - public static - class Test_rrFromWire extends TestCase { - public - void test_basic() throws IOException { - byte[] raw = new byte[] {5, '-', '8', '.', '1', '2', 6, '1', '2', '3', '.', '0', '7', 3, '0', '.', '0'}; - DnsInput in = new DnsInput(raw); - - GPOSRecord gr = new GPOSRecord(); - gr.rrFromWire(in); - assertEquals(new Double(-8.12), new Double(gr.getLongitude())); - assertEquals(new Double(123.07), new Double(gr.getLatitude())); - assertEquals(new Double(0.0), new Double(gr.getAltitude())); - } - - public - void test_longitude_toosmall() throws IOException { - byte[] raw = new byte[] {5, '-', '9', '5', '.', '0', 6, '1', '2', '3', '.', '0', '7', 3, '0', '.', '0'}; - DnsInput in = new DnsInput(raw); - - GPOSRecord gr = new GPOSRecord(); - try { - gr.rrFromWire(in); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - } - } - - public - void test_longitude_toobig() throws IOException { - byte[] raw = new byte[] {5, '1', '8', '5', '.', '0', 6, '1', '2', '3', '.', '0', '7', 3, '0', '.', '0'}; - DnsInput in = new DnsInput(raw); - - GPOSRecord gr = new GPOSRecord(); - try { - gr.rrFromWire(in); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - } - } - - public - void test_latitude_toosmall() throws IOException { - byte[] raw = new byte[] {5, '-', '8', '5', '.', '0', 6, '-', '1', '9', '0', '.', '0', 3, '0', '.', '0'}; - DnsInput in = new DnsInput(raw); - - GPOSRecord gr = new GPOSRecord(); - try { - gr.rrFromWire(in); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - } - } - - public - void test_latitude_toobig() throws IOException { - byte[] raw = new byte[] {5, '-', '8', '5', '.', '0', 6, '2', '1', '9', '0', '.', '0', 3, '0', '.', '0'}; - DnsInput in = new DnsInput(raw); - - GPOSRecord gr = new GPOSRecord(); - try { - gr.rrFromWire(in); - fail("WireParseException not thrown"); - } catch (WireParseException e) { - } - } - } - - - public static - class Test_rdataFromString extends TestCase { - public - void test_basic() throws IOException { - Tokenizer t = new Tokenizer("10.45 171.121212 1010787"); - - GPOSRecord gr = new GPOSRecord(); - gr.rdataFromString(t, null); - assertEquals(new Double(10.45), new Double(gr.getLongitude())); - assertEquals(new Double(171.121212), new Double(gr.getLatitude())); - assertEquals(new Double(1010787), new Double(gr.getAltitude())); - } - - public - void test_longitude_toosmall() throws IOException { - Tokenizer t = new Tokenizer("-100.390 171.121212 1010787"); - - GPOSRecord gr = new GPOSRecord(); - try { - gr.rdataFromString(t, null); - fail("IOException not thrown"); - } catch (IOException e) { - } - } - - public - void test_longitude_toobig() throws IOException { - Tokenizer t = new Tokenizer("90.00001 171.121212 1010787"); - - GPOSRecord gr = new GPOSRecord(); - try { - gr.rdataFromString(t, null); - fail("IOException not thrown"); - } catch (IOException e) { - } - } - - public - void test_latitude_toosmall() throws IOException { - Tokenizer t = new Tokenizer("0.0 -180.01 1010787"); - - GPOSRecord gr = new GPOSRecord(); - try { - gr.rdataFromString(t, null); - fail("IOException not thrown"); - } catch (IOException e) { - } - } - - public - void test_latitude_toobig() throws IOException { - Tokenizer t = new Tokenizer("0.0 180.01 1010787"); - - GPOSRecord gr = new GPOSRecord(); - try { - gr.rdataFromString(t, null); - fail("IOException not thrown"); - } catch (IOException e) { - } - } - - public - void test_invalid_string() throws IOException { - Tokenizer t = new Tokenizer("1.0 2.0 \\435"); - try { - GPOSRecord gr = new GPOSRecord(); - gr.rdataFromString(t, null); - } catch (TextParseException e) { - } - } - } - - public - void test_rrToString() throws TextParseException { - String exp = "\"10.45\" \"171.121212\" \"1010787.0\""; - - GPOSRecord gr = new GPOSRecord(Name.fromString("The.Name."), DnsClass.IN, 0x123, 10.45, 171.121212, 1010787); - - StringBuilder sb = new StringBuilder(); - gr.rrToString(sb); - assertEquals(exp, sb.toString()); - } - - public - void test_rrToWire() throws TextParseException { - GPOSRecord gr = new GPOSRecord(Name.fromString("The.Name."), DnsClass.IN, 0x123, -10.45, 120.0, 111.0); - - byte[] exp = new byte[] {6, '-', '1', '0', '.', '4', '5', 5, '1', '2', '0', '.', '0', 5, '1', '1', '1', '.', '0'}; - - DnsOutput out = new DnsOutput(); - gr.rrToWire(out, null, true); - - byte[] bar = out.toByteArray(); - - assertEquals(exp.length, bar.length); - for (int i = 0; i < exp.length; ++i) { - assertEquals("i=" + i, exp[i], bar[i]); - } - } - - public static - Test suite() { - TestSuite s = new TestSuite(); - s.addTestSuite(Test_Ctor_6arg_doubles.class); - s.addTestSuite(Test_Ctor_6arg_Strings.class); - s.addTestSuite(Test_rrFromWire.class); - s.addTestSuite(Test_rdataFromString.class); - s.addTestSuite(GPOSRecordTest.class); - return s; - } -} diff --git a/test/dorkbox/network/dns/records/HINFORecordTest.java b/test/dorkbox/network/dns/records/HINFORecordTest.java deleted file mode 100644 index 6241e2c9..00000000 --- a/test/dorkbox/network/dns/records/HINFORecordTest.java +++ /dev/null @@ -1,200 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.util.Arrays; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.TestCase; - -public -class HINFORecordTest extends TestCase { - public - void test_ctor_0arg() { - HINFORecord dr = new HINFORecord(); - assertNull(dr.getName()); - assertEquals(0, dr.getType()); - assertEquals(0, dr.getDClass()); - assertEquals(0, dr.getTTL()); - } - - public - void test_getObject() { - HINFORecord dr = new HINFORecord(); - DnsRecord r = dr.getObject(); - assertTrue(r instanceof HINFORecord); - } - - public - void test_ctor_5arg() throws TextParseException { - Name n = Name.fromString("The.Name."); - long ttl = 0xABCDL; - String cpu = "i686 Intel(R) Pentium(R) M processor 1.70GHz GenuineIntel GNU/Linux"; - String os = "Linux troy 2.6.10-gentoo-r6 #8 Wed Apr 6 21:25:04 MDT 2005"; - - HINFORecord dr = new HINFORecord(n, DnsClass.IN, ttl, cpu, os); - assertEquals(n, dr.getName()); - assertEquals(DnsClass.IN, dr.getDClass()); - assertEquals(DnsRecordType.HINFO, dr.getType()); - assertEquals(ttl, dr.getTTL()); - assertEquals(cpu, dr.getCPU()); - assertEquals(os, dr.getOS()); - } - - public - void test_ctor_5arg_invalid_CPU() throws TextParseException { - Name n = Name.fromString("The.Name."); - long ttl = 0xABCDL; - String cpu = "i686 Intel(R) Pentium(R) M \\256 processor 1.70GHz GenuineIntel GNU/Linux"; - String os = "Linux troy 2.6.10-gentoo-r6 #8 Wed Apr 6 21:25:04 MDT 2005"; - - try { - new HINFORecord(n, DnsClass.IN, ttl, cpu, os); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_ctor_5arg_invalid_OS() throws TextParseException { - Name n = Name.fromString("The.Name."); - long ttl = 0xABCDL; - String cpu = "i686 Intel(R) Pentium(R) M processor 1.70GHz GenuineIntel GNU/Linux"; - String os = "Linux troy 2.6.10-gentoo-r6 \\1 #8 Wed Apr 6 21:25:04 MDT 2005"; - - try { - new HINFORecord(n, DnsClass.IN, ttl, cpu, os); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_rrFromWire() throws IOException { - String cpu = "Intel(R) Pentium(R) M processor 1.70GHz"; - String os = "Linux troy 2.6.10-gentoo-r6"; - - byte[] raw = new byte[] {39, 'I', 'n', 't', 'e', 'l', '(', 'R', ')', ' ', 'P', 'e', 'n', 't', 'i', 'u', 'm', '(', 'R', ')', ' ', - 'M', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', 'o', 'r', ' ', '1', '.', '7', '0', 'G', 'H', 'z', 27, 'L', - 'i', 'n', 'u', 'x', ' ', 't', 'r', 'o', 'y', ' ', '2', '.', '6', '.', '1', '0', '-', 'g', 'e', 'n', 't', - 'o', 'o', '-', 'r', '6'}; - - DnsInput in = new DnsInput(raw); - - HINFORecord dr = new HINFORecord(); - dr.rrFromWire(in); - assertEquals(cpu, dr.getCPU()); - assertEquals(os, dr.getOS()); - } - - public - void test_rdataFromString() throws IOException { - String cpu = "Intel(R) Pentium(R) M processor 1.70GHz"; - String os = "Linux troy 2.6.10-gentoo-r6"; - - Tokenizer t = new Tokenizer("\"" + cpu + "\" \"" + os + "\""); - - HINFORecord dr = new HINFORecord(); - dr.rdataFromString(t, null); - assertEquals(cpu, dr.getCPU()); - assertEquals(os, dr.getOS()); - } - - public - void test_rdataFromString_invalid_CPU() throws IOException { - String cpu = "Intel(R) Pentium(R) \\388 M processor 1.70GHz"; - String os = "Linux troy 2.6.10-gentoo-r6"; - - Tokenizer t = new Tokenizer("\"" + cpu + "\" \"" + os + "\""); - - HINFORecord dr = new HINFORecord(); - try { - dr.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_rdataFromString_invalid_OS() throws IOException { - String cpu = "Intel(R) Pentium(R) M processor 1.70GHz"; - - Tokenizer t = new Tokenizer("\"" + cpu + "\""); - - HINFORecord dr = new HINFORecord(); - try { - dr.rdataFromString(t, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } - - public - void test_rrToString() throws TextParseException { - String cpu = "Intel(R) Pentium(R) M processor 1.70GHz"; - String os = "Linux troy 2.6.10-gentoo-r6"; - - String exp = "\"" + cpu + "\" \"" + os + "\""; - - HINFORecord dr = new HINFORecord(Name.fromString("The.Name."), DnsClass.IN, 0x123, cpu, os); - StringBuilder sb = new StringBuilder(); - dr.rrToString(sb); - assertEquals(exp, sb.toString()); - } - - public - void test_rrToWire() throws TextParseException { - String cpu = "Intel(R) Pentium(R) M processor 1.70GHz"; - String os = "Linux troy 2.6.10-gentoo-r6"; - byte[] raw = new byte[] {39, 'I', 'n', 't', 'e', 'l', '(', 'R', ')', ' ', 'P', 'e', 'n', 't', 'i', 'u', 'm', '(', 'R', ')', ' ', - 'M', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', 'o', 'r', ' ', '1', '.', '7', '0', 'G', 'H', 'z', 27, 'L', - 'i', 'n', 'u', 'x', ' ', 't', 'r', 'o', 'y', ' ', '2', '.', '6', '.', '1', '0', '-', 'g', 'e', 'n', 't', - 'o', 'o', '-', 'r', '6'}; - - HINFORecord dr = new HINFORecord(Name.fromString("The.Name."), DnsClass.IN, 0x123, cpu, os); - - DnsOutput out = new DnsOutput(); - dr.rrToWire(out, null, true); - - assertTrue(Arrays.equals(raw, out.toByteArray())); - } -} diff --git a/test/dorkbox/network/dns/records/HeaderTest.java b/test/dorkbox/network/dns/records/HeaderTest.java deleted file mode 100644 index 99576253..00000000 --- a/test/dorkbox/network/dns/records/HeaderTest.java +++ /dev/null @@ -1,455 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.constants.DnsOpCode; -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.constants.Flags; -import junit.framework.TestCase; - -public -class HeaderTest extends TestCase { - private Header m_h; - - @Override - public - void setUp() { - m_h = new Header(0xABCD); // 43981 - } - - public - void test_fixture_state() { - assertEquals(0xABCD, m_h.getID()); - - boolean[] flags = m_h.getFlags(); - for (int i = 0; i < flags.length; ++i) { - assertFalse(flags[i]); - } - assertEquals(0, m_h.getRcode()); - assertEquals(0, m_h.getOpcode()); - assertEquals(0, m_h.getCount(0)); - assertEquals(0, m_h.getCount(1)); - assertEquals(0, m_h.getCount(2)); - assertEquals(0, m_h.getCount(3)); - } - - public - void test_ctor_0arg() { - m_h = new Header(); - assertTrue(0 <= m_h.getID() && m_h.getID() < 0xFFFF); - - boolean[] flags = m_h.getFlags(); - for (int i = 0; i < flags.length; ++i) { - assertFalse(flags[i]); - } - assertEquals(0, m_h.getRcode()); - assertEquals(0, m_h.getOpcode()); - assertEquals(0, m_h.getCount(0)); - assertEquals(0, m_h.getCount(1)); - assertEquals(0, m_h.getCount(2)); - assertEquals(0, m_h.getCount(3)); - } - - public - void test_ctor_DNSInput() throws IOException { - byte[] raw = new byte[] {(byte) 0x12, (byte) 0xAB, // ID - (byte) 0x8F, (byte) 0xBD, // flags: 1 0001 1 1 1 1 011 1101 - (byte) 0x65, (byte) 0x1C, // QDCOUNT - (byte) 0x10, (byte) 0xF0, // ANCOUNT - (byte) 0x98, (byte) 0xBA, // NSCOUNT - (byte) 0x71, (byte) 0x90}; // ARCOUNT - - m_h = new Header(new DnsInput(raw)); - - assertEquals(0x12AB, m_h.getID()); - - boolean[] flags = m_h.getFlags(); - - assertTrue(flags[0]); - - assertEquals(1, m_h.getOpcode()); - - assertTrue(flags[5]); - - assertTrue(flags[6]); - - assertTrue(flags[7]); - - assertTrue(flags[8]); - - assertFalse(flags[9]); - assertTrue(flags[10]); - assertTrue(flags[11]); - - assertEquals(0xD, m_h.getRcode()); - - assertEquals(0x651C, m_h.getCount(0)); - assertEquals(0x10F0, m_h.getCount(1)); - assertEquals(0x98BA, m_h.getCount(2)); - assertEquals(0x7190, m_h.getCount(3)); - } - - public - void test_toWire() throws IOException { - byte[] raw = new byte[] {(byte) 0x12, (byte) 0xAB, // ID - (byte) 0x8F, (byte) 0xBD, // flags: 1 0001 1 1 1 1 011 1101 - (byte) 0x65, (byte) 0x1C, // QDCOUNT - (byte) 0x10, (byte) 0xF0, // ANCOUNT - (byte) 0x98, (byte) 0xBA, // NSCOUNT - (byte) 0x71, (byte) 0x90}; // ARCOUNT - - m_h = new Header(raw); - - DnsOutput dout = new DnsOutput(); - m_h.toWire(dout); - - byte[] out = dout.toByteArray(); - - assertEquals(12, out.length); - for (int i = 0; i < out.length; ++i) { - assertEquals(raw[i], out[i]); - } - - m_h.setOpcode(0xA); // 1010 - assertEquals(0xA, m_h.getOpcode()); - m_h.setRcode(0x7); // 0111 - - // flags is now: 1101 0111 1011 0111 - - raw[2] = (byte) 0xD7; - raw[3] = (byte) 0xB7; - - out = m_h.toWire(); - - assertEquals(12, out.length); - for (int i = 0; i < out.length; ++i) { - assertEquals("i=" + i, raw[i], out[i]); - } - } - - public - void test_flags() { - m_h.setFlag(Flags.toFlag(0)); - m_h.setFlag(Flags.toFlag(5)); - assertTrue(m_h.getFlag(Flags.toFlag(0))); - assertTrue(m_h.getFlags()[0]); - assertTrue(m_h.getFlag(Flags.toFlag(5))); - assertTrue(m_h.getFlags()[5]); - - m_h.unsetFlag(Flags.toFlag(0)); - assertFalse(m_h.getFlag(Flags.toFlag(0))); - assertFalse(m_h.getFlags()[0]); - assertTrue(m_h.getFlag(Flags.toFlag(5))); - assertTrue(m_h.getFlags()[5]); - - m_h.unsetFlag(Flags.toFlag(5)); - assertFalse(m_h.getFlag(Flags.toFlag(0))); - assertFalse(m_h.getFlags()[0]); - assertFalse(m_h.getFlag(Flags.toFlag(5))); - assertFalse(m_h.getFlags()[5]); - - boolean[] flags = m_h.getFlags(); - for (int i = 0; i < flags.length; ++i) { - if ((i > 0 && i < 5) || i > 11) { - continue; - } - assertFalse(flags[i]); - } - } - - public - void test_flags_invalid() { - try { - m_h.setFlag(Flags.toFlag(-1)); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - m_h.setFlag(Flags.toFlag(1)); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - m_h.setFlag(Flags.toFlag(16)); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - m_h.unsetFlag(Flags.toFlag(-1)); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - m_h.unsetFlag(Flags.toFlag(13)); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - m_h.unsetFlag(Flags.toFlag(16)); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - m_h.getFlag(Flags.toFlag(-1)); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - m_h.getFlag(Flags.toFlag(4)); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - m_h.getFlag(Flags.toFlag(16)); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_ID() { - assertEquals(0xABCD, m_h.getID()); - - m_h = new Header(); - - int id = m_h.getID(); - assertEquals(id, m_h.getID()); - assertTrue(id >= 0 && id < 0xffff); - - m_h.setID(0xDCBA); - assertEquals(0xDCBA, m_h.getID()); - } - - public - void test_setID_invalid() { - try { - m_h.setID(0x10000); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - m_h.setID(-1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_Rcode() { - assertEquals(0, m_h.getRcode()); - - m_h.setRcode(0xA); // 1010 - assertEquals(0xA, m_h.getRcode()); - for (int i = 0; i < 12; ++i) { - if ((i > 0 && i < 5) || i > 11) { - continue; - } - assertFalse(m_h.getFlag(Flags.toFlag(i))); - } - } - - public - void test_setRcode_invalid() { - try { - m_h.setRcode(-1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - m_h.setRcode(0x100); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_Opcode() { - assertEquals(0, m_h.getOpcode()); - - m_h.setOpcode(0xE); // 1110 - assertEquals(0xE, m_h.getOpcode()); - - assertFalse(m_h.getFlag(Flags.toFlag(0))); - for (int i = 5; i < 12; ++i) { - assertFalse(m_h.getFlag(Flags.toFlag(i))); - } - assertEquals(0, m_h.getRcode()); - } - - public - void test_setOpcode_invalid() { - try { - m_h.setOpcode(-1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - m_h.setOpcode(0x100); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_Count() { - m_h.setCount(2, 0x1E); - assertEquals(0, m_h.getCount(0)); - assertEquals(0, m_h.getCount(1)); - assertEquals(0x1E, m_h.getCount(2)); - assertEquals(0, m_h.getCount(3)); - - m_h.incCount(0); - assertEquals(1, m_h.getCount(0)); - - m_h.decCount(2); - assertEquals(0x1E - 1, m_h.getCount(2)); - } - - public - void test_setCount_invalid() { - try { - m_h.setCount(-1, 0); - fail("ArrayIndexOutOfBoundsException not thrown"); - } catch (ArrayIndexOutOfBoundsException e) { - } - try { - m_h.setCount(4, 0); - fail("ArrayIndexOutOfBoundsException not thrown"); - } catch (ArrayIndexOutOfBoundsException e) { - } - - try { - m_h.setCount(0, -1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - try { - m_h.setCount(3, 0x10000); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_getCount_invalid() { - try { - m_h.getCount(-1); - fail("ArrayIndexOutOfBoundsException not thrown"); - } catch (ArrayIndexOutOfBoundsException e) { - } - try { - m_h.getCount(4); - fail("ArrayIndexOutOfBoundsException not thrown"); - } catch (ArrayIndexOutOfBoundsException e) { - } - } - - public - void test_incCount_invalid() { - m_h.setCount(1, 0xFFFF); - try { - m_h.incCount(1); - fail("IllegalStateException not thrown"); - } catch (IllegalStateException e) { - } - } - - public - void test_decCount_invalid() { - m_h.setCount(2, 0); - try { - m_h.decCount(2); - fail("IllegalStateException not thrown"); - } catch (IllegalStateException e) { - } - } - - public - void test_toString() { - m_h.setOpcode(DnsOpCode.STATUS); - m_h.setRcode(DnsResponseCode.NXDOMAIN); - m_h.setFlag(Flags.QR); // qr - m_h.setFlag(Flags.RD); // rd - m_h.setFlag(Flags.RA); // ra - m_h.setFlag(Flags.CD); // cd - m_h.setCount(1, 0xFF); - m_h.setCount(2, 0x0A); - - - String text = m_h.toString(); - - assertFalse(text.indexOf("id: 43981") == -1); - assertFalse(text.indexOf("opcode: STATUS") == -1); - assertFalse(text.indexOf("status: NXDOMAIN") == -1); - assertFalse(text.indexOf(" qr ") == -1); - assertFalse(text.indexOf(" rd ") == -1); - assertFalse(text.indexOf(" ra ") == -1); - assertFalse(text.indexOf(" cd ") == -1); - assertFalse(text.indexOf("qd: 0 ") == -1); - assertFalse(text.indexOf("an: 255 ") == -1); - assertFalse(text.indexOf("au: 10 ") == -1); - assertFalse(text.indexOf("ad: 0 ") == -1); - } - - public - void test_clone() { - m_h.setOpcode(DnsOpCode.IQUERY); - m_h.setRcode(DnsResponseCode.SERVFAIL); - m_h.setFlag(Flags.QR); // qr - m_h.setFlag(Flags.RD); // rd - m_h.setFlag(Flags.RA); // ra - m_h.setFlag(Flags.CD); // cd - m_h.setCount(1, 0xFF); - m_h.setCount(2, 0x0A); - - Header h2 = (Header) m_h.clone(); - - assertNotSame(m_h, h2); - assertEquals(m_h.getID(), h2.getID()); - for (int i = 0; i < 16; ++i) { - if ((i > 0 && i < 5) || i > 11) { - continue; - } - assertEquals(m_h.getFlag(Flags.toFlag(i)), h2.getFlag(Flags.toFlag(i))); - } - for (int i = 0; i < 4; ++i) { - assertEquals(m_h.getCount(i), h2.getCount(i)); - } - } -} diff --git a/test/dorkbox/network/dns/records/KEYBaseTest.java b/test/dorkbox/network/dns/records/KEYBaseTest.java deleted file mode 100644 index d8a4e02c..00000000 --- a/test/dorkbox/network/dns/records/KEYBaseTest.java +++ /dev/null @@ -1,202 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.util.Arrays; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Options; -import dorkbox.network.dns.utils.Tokenizer; -import dorkbox.util.Base64Fast; -import junit.framework.TestCase; - -public -class KEYBaseTest extends TestCase { - private static - class TestClass extends KEYBase { - public - TestClass() {} - - public - TestClass(Name name, int type, int dclass, long ttl, int flags, int proto, int alg, byte[] key) { - super(name, type, dclass, ttl, flags, proto, alg, key); - } - - @Override - public - DnsRecord getObject() { - return null; - } - - @Override - void rdataFromString(Tokenizer st, Name origin) throws IOException { - } - } - - public - void test_ctor() throws TextParseException { - TestClass tc = new TestClass(); - assertEquals(0, tc.getFlags()); - assertEquals(0, tc.getProtocol()); - assertEquals(0, tc.getAlgorithm()); - assertNull(tc.getKey()); - - Name n = Name.fromString("my.name."); - byte[] key = new byte[] {0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}; - - tc = new TestClass(n, DnsRecordType.KEY, DnsClass.IN, 100L, 0xFF, 0xF, 0xE, key); - - assertSame(n, tc.getName()); - assertEquals(DnsRecordType.KEY, tc.getType()); - assertEquals(DnsClass.IN, tc.getDClass()); - assertEquals(100L, tc.getTTL()); - assertEquals(0xFF, tc.getFlags()); - assertEquals(0xF, tc.getProtocol()); - assertEquals(0xE, tc.getAlgorithm()); - assertTrue(Arrays.equals(key, tc.getKey())); - } - - public - void test_rrFromWire() throws IOException { - byte[] raw = new byte[] {(byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x19, 1, 2, 3, 4, 5}; - DnsInput in = new DnsInput(raw); - - TestClass tc = new TestClass(); - tc.rrFromWire(in); - - assertEquals(0xABCD, tc.getFlags()); - assertEquals(0xEF, tc.getProtocol()); - assertEquals(0x19, tc.getAlgorithm()); - assertTrue(Arrays.equals(new byte[] {1, 2, 3, 4, 5}, tc.getKey())); - - - raw = new byte[] {(byte) 0xBA, (byte) 0xDA, (byte) 0xFF, (byte) 0x28}; - in = new DnsInput(raw); - - tc = new TestClass(); - tc.rrFromWire(in); - - assertEquals(0xBADA, tc.getFlags()); - assertEquals(0xFF, tc.getProtocol()); - assertEquals(0x28, tc.getAlgorithm()); - assertNull(tc.getKey()); - } - - public - void test_rrToString() throws IOException, TextParseException { - Name n = Name.fromString("my.name."); - byte[] key = new byte[] {0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}; - - TestClass tc = new TestClass(n, DnsRecordType.KEY, DnsClass.IN, 100L, 0xFF, 0xF, 0xE, null); - - StringBuilder sb = new StringBuilder(); - tc.rrToString(sb); - String out = sb.toString(); - - assertEquals("255 15 14", out); - - tc = new TestClass(n, DnsRecordType.KEY, DnsClass.IN, 100L, 0xFF, 0xF, 0xE, key); - - sb = new StringBuilder(); - tc.rrToString(sb); - out = sb.toString(); - - assertEquals("255 15 14 " + Base64Fast.encode2(key), out); - - Options.set("multiline"); - - sb = new StringBuilder(); - tc.rrToString(sb); - out = sb.toString(); - - assertEquals("255 15 14 (\n\t" + Base64Fast.encode2(key) + " ) ; key_tag = 18509", out); - - Options.unset("multiline"); - } - - public - void test_getFootprint() throws TextParseException { - Name n = Name.fromString("my.name."); - byte[] key = new byte[] {0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}; - - TestClass tc = new TestClass(n, DnsRecordType.KEY, DnsClass.IN, 100L, 0xFF, 0xF, DNSSEC.Algorithm.RSAMD5, key); - - int foot = tc.getFootprint(); - // second-to-last and third-to-last bytes of key for RSAMD5 - assertEquals(0xD0E, foot); - assertEquals(foot, tc.getFootprint()); - - // key with an odd number of bytes - tc = new TestClass(n, DnsRecordType.KEY, DnsClass.IN, 100L, 0x89AB, 0xCD, 0xEF, new byte[] {0x12, 0x34, 0x56}); - - // rrToWire gives: { 0x89, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56 } - // 89AB + CDEF + 1234 + 5600 = 1BCFE - // 1BFCE + 1 = 1BFCF & FFFF = BFCF - foot = tc.getFootprint(); - assertEquals(0xBFCF, foot); - assertEquals(foot, tc.getFootprint()); - - // empty - tc = new TestClass(); - assertEquals(0, tc.getFootprint()); - } - - public - void test_rrToWire() throws IOException, TextParseException { - Name n = Name.fromString("my.name."); - byte[] key = new byte[] {0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF}; - - TestClass tc = new TestClass(n, DnsRecordType.KEY, DnsClass.IN, 100L, 0x7689, 0xAB, 0xCD, key); - - byte[] exp = new byte[] {(byte) 0x76, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; - - DnsOutput o = new DnsOutput(); - - // canonical - tc.rrToWire(o, null, true); - assertTrue(Arrays.equals(exp, o.toByteArray())); - - // not canonical - o = new DnsOutput(); - tc.rrToWire(o, null, false); - assertTrue(Arrays.equals(exp, o.toByteArray())); - } -} diff --git a/test/dorkbox/network/dns/records/KEYRecordTest.java b/test/dorkbox/network/dns/records/KEYRecordTest.java deleted file mode 100644 index f42d1c3a..00000000 --- a/test/dorkbox/network/dns/records/KEYRecordTest.java +++ /dev/null @@ -1,202 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.UnknownHostException; -import java.util.Arrays; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.RelativeNameException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.TestCase; - -public -class KEYRecordTest extends TestCase { - public - void test_ctor_0arg() throws UnknownHostException { - KEYRecord ar = new KEYRecord(); - assertNull(ar.getName()); - assertEquals(0, ar.getType()); - assertEquals(0, ar.getDClass()); - assertEquals(0, ar.getTTL()); - assertEquals(0, ar.getAlgorithm()); - assertEquals(0, ar.getFlags()); - assertEquals(0, ar.getFootprint()); - assertEquals(0, ar.getProtocol()); - assertNull(ar.getKey()); - } - - public - void test_getObject() { - KEYRecord ar = new KEYRecord(); - DnsRecord r = ar.getObject(); - assertTrue(r instanceof KEYRecord); - } - - public - void test_ctor_7arg() throws TextParseException { - Name n = Name.fromString("My.Absolute.Name."); - Name r = Name.fromString("My.Relative.Name"); - byte[] key = new byte[] {0, 1, 3, 5, 7, 9}; - - KEYRecord kr = new KEYRecord(n, DnsClass.IN, 0x24AC, 0x9832, 0x12, 0x67, key); - assertEquals(n, kr.getName()); - assertEquals(DnsRecordType.KEY, kr.getType()); - assertEquals(DnsClass.IN, kr.getDClass()); - assertEquals(0x24AC, kr.getTTL()); - assertEquals(0x9832, kr.getFlags()); - assertEquals(0x12, kr.getProtocol()); - assertEquals(0x67, kr.getAlgorithm()); - assertTrue(Arrays.equals(key, kr.getKey())); - - // a relative name - try { - new KEYRecord(r, DnsClass.IN, 0x24AC, 0x9832, 0x12, 0x67, key); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException e) { - } - } - - public - void test_Protocol_string() { - // a regular one - assertEquals("DNSSEC", KEYRecord.Protocol.string(KEYRecord.Protocol.DNSSEC)); - // a unassigned value within range - assertEquals("254", KEYRecord.Protocol.string(0xFE)); - // too low - try { - KEYRecord.Protocol.string(-1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - // too high - try { - KEYRecord.Protocol.string(0x100); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_Protocol_value() { - // a regular one - assertEquals(KEYRecord.Protocol.IPSEC, KEYRecord.Protocol.value("IPSEC")); - // a unassigned value within range - assertEquals(254, KEYRecord.Protocol.value("254")); - // too low - assertEquals(-1, KEYRecord.Protocol.value("-2")); - // too high - assertEquals(-1, KEYRecord.Protocol.value("256")); - } - - public - void test_Flags_value() { - // numeric - - // lower bound - assertEquals(-1, KEYRecord.Flags.value("-2")); - assertEquals(0, KEYRecord.Flags.value("0")); - // in the middle - assertEquals(0xAB35, KEYRecord.Flags.value(0xAB35 + "")); - // upper bound - assertEquals(0xFFFF, KEYRecord.Flags.value(0xFFFF + "")); - assertEquals(-1, KEYRecord.Flags.value(0x10000 + "")); - - // textual - - // single - assertEquals(KEYRecord.Flags.EXTEND, KEYRecord.Flags.value("EXTEND")); - // single invalid - assertEquals(-1, KEYRecord.Flags.value("NOT_A_VALID_NAME")); - // multiple - assertEquals(KEYRecord.Flags.NOAUTH | KEYRecord.Flags.FLAG10 | KEYRecord.Flags.ZONE, KEYRecord.Flags.value("NOAUTH|ZONE|FLAG10")); - // multiple invalid - assertEquals(-1, KEYRecord.Flags.value("NOAUTH|INVALID_NAME|FLAG10")); - // pathological - assertEquals(0, KEYRecord.Flags.value("|")); - } - - public - void test_rdataFromString() throws IOException, TextParseException { - // basic - KEYRecord kr = new KEYRecord(); - Tokenizer st = new Tokenizer("NOAUTH|ZONE|FLAG10 EMAIL RSASHA1 AQIDBAUGBwgJ"); - kr.rdataFromString(st, null); - assertEquals(KEYRecord.Flags.NOAUTH | KEYRecord.Flags.FLAG10 | KEYRecord.Flags.ZONE, kr.getFlags()); - assertEquals(KEYRecord.Protocol.EMAIL, kr.getProtocol()); - assertEquals(DNSSEC.Algorithm.RSASHA1, kr.getAlgorithm()); - assertTrue(Arrays.equals(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9}, kr.getKey())); - - // basic w/o key - kr = new KEYRecord(); - st = new Tokenizer("NOAUTH|NOKEY|FLAG10 TLS 3"); - kr.rdataFromString(st, null); - assertEquals(KEYRecord.Flags.NOAUTH | KEYRecord.Flags.FLAG10 | KEYRecord.Flags.NOKEY, kr.getFlags()); - assertEquals(KEYRecord.Protocol.TLS, kr.getProtocol()); - assertEquals(3, kr.getAlgorithm()); // Was ECC - assertNull(kr.getKey()); - - // invalid flags - kr = new KEYRecord(); - st = new Tokenizer("NOAUTH|ZONE|JUNK EMAIL RSASHA1 AQIDBAUGBwgJ"); - try { - kr.rdataFromString(st, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - // invalid protocol - kr = new KEYRecord(); - st = new Tokenizer("NOAUTH|ZONE RSASHA1 3 AQIDBAUGBwgJ"); - try { - kr.rdataFromString(st, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - - // invalid algorithm - kr = new KEYRecord(); - st = new Tokenizer("NOAUTH|ZONE EMAIL ZONE AQIDBAUGBwgJ"); - try { - kr.rdataFromString(st, null); - fail("TextParseException not thrown"); - } catch (TextParseException e) { - } - } -} diff --git a/test/dorkbox/network/dns/records/KXRecordTest.java b/test/dorkbox/network/dns/records/KXRecordTest.java deleted file mode 100644 index 5213a373..00000000 --- a/test/dorkbox/network/dns/records/KXRecordTest.java +++ /dev/null @@ -1,66 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class KXRecordTest extends TestCase { - public - void test_getObject() { - KXRecord d = new KXRecord(); - DnsRecord r = d.getObject(); - assertTrue(r instanceof KXRecord); - } - - public - void test_ctor_5arg() throws TextParseException { - Name n = Name.fromString("My.Name."); - Name m = Name.fromString("My.OtherName."); - - KXRecord d = new KXRecord(n, DnsClass.IN, 0xABCDEL, 0xF1, m); - assertEquals(n, d.getName()); - assertEquals(DnsRecordType.KX, d.getType()); - assertEquals(DnsClass.IN, d.getDClass()); - assertEquals(0xABCDEL, d.getTTL()); - assertEquals(0xF1, d.getPreference()); - assertEquals(m, d.getTarget()); - assertEquals(m, d.getAdditionalName()); - } -} diff --git a/test/dorkbox/network/dns/records/MBRecordTest.java b/test/dorkbox/network/dns/records/MBRecordTest.java deleted file mode 100644 index 9cf1c26f..00000000 --- a/test/dorkbox/network/dns/records/MBRecordTest.java +++ /dev/null @@ -1,73 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class MBRecordTest extends TestCase { - public - void test_ctor_0arg() { - MBRecord d = new MBRecord(); - assertNull(d.getName()); - assertNull(d.getAdditionalName()); - assertNull(d.getMailbox()); - } - - public - void test_ctor_4arg() throws TextParseException { - Name n = Name.fromString("my.name."); - Name a = Name.fromString("my.alias."); - - MBRecord d = new MBRecord(n, DnsClass.IN, 0xABCDEL, a); - assertEquals(n, d.getName()); - assertEquals(DnsRecordType.MB, d.getType()); - assertEquals(DnsClass.IN, d.getDClass()); - assertEquals(0xABCDEL, d.getTTL()); - assertEquals(a, d.getAdditionalName()); - assertEquals(a, d.getMailbox()); - } - - public - void test_getObject() { - MBRecord d = new MBRecord(); - DnsRecord r = d.getObject(); - assertTrue(r instanceof MBRecord); - } -} diff --git a/test/dorkbox/network/dns/records/MDRecordTest.java b/test/dorkbox/network/dns/records/MDRecordTest.java deleted file mode 100644 index 7ab3258a..00000000 --- a/test/dorkbox/network/dns/records/MDRecordTest.java +++ /dev/null @@ -1,73 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class MDRecordTest extends TestCase { - public - void test_ctor_0arg() { - MDRecord d = new MDRecord(); - assertNull(d.getName()); - assertNull(d.getAdditionalName()); - assertNull(d.getMailAgent()); - } - - public - void test_ctor_4arg() throws TextParseException { - Name n = Name.fromString("my.name."); - Name a = Name.fromString("my.alias."); - - MDRecord d = new MDRecord(n, DnsClass.IN, 0xABCDEL, a); - assertEquals(n, d.getName()); - assertEquals(DnsRecordType.MD, d.getType()); - assertEquals(DnsClass.IN, d.getDClass()); - assertEquals(0xABCDEL, d.getTTL()); - assertEquals(a, d.getAdditionalName()); - assertEquals(a, d.getMailAgent()); - } - - public - void test_getObject() { - MDRecord d = new MDRecord(); - DnsRecord r = d.getObject(); - assertTrue(r instanceof MDRecord); - } -} diff --git a/test/dorkbox/network/dns/records/MFRecordTest.java b/test/dorkbox/network/dns/records/MFRecordTest.java deleted file mode 100644 index ba735940..00000000 --- a/test/dorkbox/network/dns/records/MFRecordTest.java +++ /dev/null @@ -1,73 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class MFRecordTest extends TestCase { - public - void test_ctor_0arg() { - MFRecord d = new MFRecord(); - assertNull(d.getName()); - assertNull(d.getAdditionalName()); - assertNull(d.getMailAgent()); - } - - public - void test_ctor_4arg() throws TextParseException { - Name n = Name.fromString("my.name."); - Name a = Name.fromString("my.alias."); - - MFRecord d = new MFRecord(n, DnsClass.IN, 0xABCDEL, a); - assertEquals(n, d.getName()); - assertEquals(DnsRecordType.MF, d.getType()); - assertEquals(DnsClass.IN, d.getDClass()); - assertEquals(0xABCDEL, d.getTTL()); - assertEquals(a, d.getAdditionalName()); - assertEquals(a, d.getMailAgent()); - } - - public - void test_getObject() { - MFRecord d = new MFRecord(); - DnsRecord r = d.getObject(); - assertTrue(r instanceof MFRecord); - } -} diff --git a/test/dorkbox/network/dns/records/MGRecordTest.java b/test/dorkbox/network/dns/records/MGRecordTest.java deleted file mode 100644 index 8c5b28b7..00000000 --- a/test/dorkbox/network/dns/records/MGRecordTest.java +++ /dev/null @@ -1,71 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class MGRecordTest extends TestCase { - public - void test_ctor_0arg() { - MGRecord d = new MGRecord(); - assertNull(d.getName()); - assertNull(d.getMailbox()); - } - - public - void test_ctor_4arg() throws TextParseException { - Name n = Name.fromString("my.name."); - Name a = Name.fromString("my.alias."); - - MGRecord d = new MGRecord(n, DnsClass.IN, 0xABCDEL, a); - assertEquals(n, d.getName()); - assertEquals(DnsRecordType.MG, d.getType()); - assertEquals(DnsClass.IN, d.getDClass()); - assertEquals(0xABCDEL, d.getTTL()); - assertEquals(a, d.getMailbox()); - } - - public - void test_getObject() { - MGRecord d = new MGRecord(); - DnsRecord r = d.getObject(); - assertTrue(r instanceof MGRecord); - } -} diff --git a/test/dorkbox/network/dns/records/MRRecordTest.java b/test/dorkbox/network/dns/records/MRRecordTest.java deleted file mode 100644 index d2c2651b..00000000 --- a/test/dorkbox/network/dns/records/MRRecordTest.java +++ /dev/null @@ -1,71 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class MRRecordTest extends TestCase { - public - void test_ctor_0arg() { - MRRecord d = new MRRecord(); - assertNull(d.getName()); - assertNull(d.getNewName()); - } - - public - void test_ctor_4arg() throws TextParseException { - Name n = Name.fromString("my.name."); - Name a = Name.fromString("my.alias."); - - MRRecord d = new MRRecord(n, DnsClass.IN, 0xABCDEL, a); - assertEquals(n, d.getName()); - assertEquals(DnsRecordType.MR, d.getType()); - assertEquals(DnsClass.IN, d.getDClass()); - assertEquals(0xABCDEL, d.getTTL()); - assertEquals(a, d.getNewName()); - } - - public - void test_getObject() { - MRRecord d = new MRRecord(); - DnsRecord r = d.getObject(); - assertTrue(r instanceof MRRecord); - } -} diff --git a/test/dorkbox/network/dns/records/MXRecordTest.java b/test/dorkbox/network/dns/records/MXRecordTest.java deleted file mode 100644 index a998f20b..00000000 --- a/test/dorkbox/network/dns/records/MXRecordTest.java +++ /dev/null @@ -1,91 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.util.Arrays; - -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class MXRecordTest extends TestCase { - public - void test_getObject() { - MXRecord d = new MXRecord(); - DnsRecord r = d.getObject(); - assertTrue(r instanceof MXRecord); - } - - public - void test_ctor_5arg() throws TextParseException { - Name n = Name.fromString("My.Name."); - Name m = Name.fromString("My.OtherName."); - - MXRecord d = new MXRecord(n, DnsClass.IN, 0xABCDEL, 0xF1, m); - assertEquals(n, d.getName()); - assertEquals(DnsRecordType.MX, d.getType()); - assertEquals(DnsClass.IN, d.getDClass()); - assertEquals(0xABCDEL, d.getTTL()); - assertEquals(0xF1, d.getPriority()); - assertEquals(m, d.getTarget()); - assertEquals(m, d.getAdditionalName()); - } - - public - void test_rrToWire() throws TextParseException { - Name n = Name.fromString("My.Name."); - Name m = Name.fromString("M.O.n."); - - MXRecord mr = new MXRecord(n, DnsClass.IN, 0xB12FL, 0x1F2B, m); - - // canonical - DnsOutput dout = new DnsOutput(); - mr.rrToWire(dout, null, true); - byte[] out = dout.toByteArray(); - byte[] exp = new byte[] {0x1F, 0x2B, 1, 'm', 1, 'o', 1, 'n', 0}; - assertTrue(Arrays.equals(exp, out)); - - // case sensitive - dout = new DnsOutput(); - mr.rrToWire(dout, null, false); - out = dout.toByteArray(); - exp = new byte[] {0x1F, 0x2B, 1, 'M', 1, 'O', 1, 'n', 0}; - assertTrue(Arrays.equals(exp, out)); - } -} diff --git a/test/dorkbox/network/dns/records/MessageTest.java b/test/dorkbox/network/dns/records/MessageTest.java deleted file mode 100644 index 5fd4f14f..00000000 --- a/test/dorkbox/network/dns/records/MessageTest.java +++ /dev/null @@ -1,124 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsOpCode; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.constants.Flags; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -public -class MessageTest { - public static - class Test_init extends TestCase { - public - void test_0arg() { - DnsMessage m = new DnsMessage(); - assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(0))); - assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(1))); - assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(2))); - assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(3))); - try { - m.getSectionArray(4); - fail("IndexOutOfBoundsException not thrown"); - } catch (IndexOutOfBoundsException ignored) { - } - Header h = m.getHeader(); - assertEquals(0, h.getCount(0)); - assertEquals(0, h.getCount(1)); - assertEquals(0, h.getCount(2)); - assertEquals(0, h.getCount(3)); - } - - public - void test_1arg() { - DnsMessage m = new DnsMessage(10); - assertEquals(new Header(10).toString(), - m.getHeader() - .toString()); - assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(0))); - assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(1))); - assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(2))); - assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(3))); - try { - m.getSectionArray(4); - fail("IndexOutOfBoundsException not thrown"); - } catch (IndexOutOfBoundsException ignored) { - } - Header h = m.getHeader(); - assertEquals(0, h.getCount(0)); - assertEquals(0, h.getCount(1)); - assertEquals(0, h.getCount(2)); - assertEquals(0, h.getCount(3)); - } - - public - void test_newQuery() throws TextParseException, UnknownHostException { - Name n = Name.fromString("The.Name."); - ARecord ar = new ARecord(n, DnsClass.IN, 1, InetAddress.getByName("192.168.101.110")); - - DnsMessage m = DnsMessage.newQuery(ar); - assertTrue(Arrays.equals(new DnsRecord[] {ar}, m.getSectionArray(DnsSection.QUESTION))); - assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(DnsSection.ANSWER))); - assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(DnsSection.AUTHORITY))); - assertTrue(Arrays.equals(new DnsRecord[0], m.getSectionArray(DnsSection.ADDITIONAL))); - - Header h = m.getHeader(); - assertEquals(1, h.getCount(DnsSection.QUESTION)); - assertEquals(0, h.getCount(DnsSection.ANSWER)); - assertEquals(0, h.getCount(DnsSection.AUTHORITY)); - assertEquals(0, h.getCount(DnsSection.ADDITIONAL)); - assertEquals(DnsOpCode.QUERY, h.getOpcode()); - assertEquals(true, h.getFlag(Flags.RD)); - } - - } - - public static - Test suite() { - TestSuite s = new TestSuite(); - s.addTestSuite(Test_init.class); - return s; - } -} diff --git a/test/dorkbox/network/dns/records/MnemonicTest.java b/test/dorkbox/network/dns/records/MnemonicTest.java deleted file mode 100644 index 2dec6cd6..00000000 --- a/test/dorkbox/network/dns/records/MnemonicTest.java +++ /dev/null @@ -1,287 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -// Mnemonic has package-level access. - -import dorkbox.network.dns.Mnemonic; -import junit.framework.TestCase; - -public -class MnemonicTest extends TestCase { - private Mnemonic m_mn; - - public - MnemonicTest(String name) { - super(name); - } - - @Override - public - void setUp() { - m_mn = new Mnemonic(MnemonicTest.class.getName() + " UPPER", Mnemonic.CASE_UPPER); - } - - public - void test_no_maximum() { - try { - m_mn.check(-1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - try { - m_mn.check(0); - } catch (IllegalArgumentException e) { - fail(e.getMessage()); - } - try { - m_mn.check(Integer.MAX_VALUE); - } catch (IllegalArgumentException e) { - fail(e.getMessage()); - } - - m_mn.setNumericAllowed(true); - - int val = m_mn.getValue("-2"); - assertEquals(-1, val); - - val = m_mn.getValue("0"); - assertEquals(0, val); - - val = m_mn.getValue("" + Integer.MAX_VALUE); - assertEquals(Integer.MAX_VALUE, val); - } - - public - void test_setMaximum() { - m_mn.setMaximum(15); - try { - m_mn.check(-1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - try { - m_mn.check(0); - } catch (IllegalArgumentException e) { - fail(e.getMessage()); - } - try { - m_mn.check(15); - } catch (IllegalArgumentException e) { - fail(e.getMessage()); - } - try { - m_mn.check(16); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - - // need numericok to exercise the usage of max in parseNumeric - m_mn.setNumericAllowed(true); - - int val = m_mn.getValue("-2"); - assertEquals(-1, val); - - val = m_mn.getValue("0"); - assertEquals(0, val); - - val = m_mn.getValue("15"); - assertEquals(15, val); - - val = m_mn.getValue("16"); - assertEquals(-1, val); - } - - public - void test_setPrefix() { - final String prefix = "A mixed CASE Prefix".toUpperCase(); - m_mn.setPrefix(prefix); - - String out = m_mn.getText(10); - assertEquals(prefix + "10", out); - - int i = m_mn.getValue(out); - assertEquals(10, i); - } - - public - void test_basic_operation() { - // setUp creates Mnemonic with CASE_UPPER - m_mn.add(10, "Ten"); - m_mn.add(20, "Twenty"); - m_mn.addAlias(20, "Veinte"); - m_mn.add(30, "Thirty"); - - String text = m_mn.getText(10); - assertEquals("TEN", text); - - text = m_mn.getText(20); - assertEquals("TWENTY", text); - - text = m_mn.getText(30); - assertEquals("THIRTY", text); - - text = m_mn.getText(40); - assertEquals("40", text); - - int value = m_mn.getValue("tEn"); - assertEquals(10, value); - - value = m_mn.getValue("twenty"); - assertEquals(20, value); - - value = m_mn.getValue("VeiNTe"); - assertEquals(20, value); - - value = m_mn.getValue("THIRTY"); - assertEquals(30, value); - } - - public - void test_basic_operation_lower() { - m_mn = new Mnemonic(MnemonicTest.class.getName() + " LOWER", Mnemonic.CASE_LOWER); - m_mn.add(10, "Ten"); - m_mn.add(20, "Twenty"); - m_mn.addAlias(20, "Veinte"); - m_mn.add(30, "Thirty"); - - String text = m_mn.getText(10); - assertEquals("ten", text); - - text = m_mn.getText(20); - assertEquals("twenty", text); - - text = m_mn.getText(30); - assertEquals("thirty", text); - - text = m_mn.getText(40); - assertEquals("40", text); - - int value = m_mn.getValue("tEn"); - assertEquals(10, value); - - value = m_mn.getValue("twenty"); - assertEquals(20, value); - - value = m_mn.getValue("VeiNTe"); - assertEquals(20, value); - - value = m_mn.getValue("THIRTY"); - assertEquals(30, value); - } - - public - void test_basic_operation_sensitive() { - m_mn = new Mnemonic(MnemonicTest.class.getName() + " SENSITIVE", Mnemonic.CASE_SENSITIVE); - m_mn.add(10, "Ten"); - m_mn.add(20, "Twenty"); - m_mn.addAlias(20, "Veinte"); - m_mn.add(30, "Thirty"); - - String text = m_mn.getText(10); - assertEquals("Ten", text); - - text = m_mn.getText(20); - assertEquals("Twenty", text); - - text = m_mn.getText(30); - assertEquals("Thirty", text); - - text = m_mn.getText(40); - assertEquals("40", text); - - int value = m_mn.getValue("Ten"); - assertEquals(10, value); - - value = m_mn.getValue("twenty"); - assertEquals(-1, value); - - value = m_mn.getValue("Twenty"); - assertEquals(20, value); - - value = m_mn.getValue("VEINTE"); - assertEquals(-1, value); - - value = m_mn.getValue("Veinte"); - assertEquals(20, value); - - value = m_mn.getValue("Thirty"); - assertEquals(30, value); - } - - public - void test_invalid_numeric() { - m_mn.setNumericAllowed(true); - int value = m_mn.getValue("Not-A-Number"); - assertEquals(-1, value); - } - - public - void test_addAll() { - m_mn.add(10, "Ten"); - m_mn.add(20, "Twenty"); - - Mnemonic mn2 = new Mnemonic("second test Mnemonic", Mnemonic.CASE_UPPER); - mn2.add(20, "Twenty"); - mn2.addAlias(20, "Veinte"); - mn2.add(30, "Thirty"); - - m_mn.addAll(mn2); - - String text = m_mn.getText(10); - assertEquals("TEN", text); - - text = m_mn.getText(20); - assertEquals("TWENTY", text); - - text = m_mn.getText(30); - assertEquals("THIRTY", text); - - text = m_mn.getText(40); - assertEquals("40", text); - - int value = m_mn.getValue("tEn"); - assertEquals(10, value); - - value = m_mn.getValue("twenty"); - assertEquals(20, value); - - value = m_mn.getValue("VeiNTe"); - assertEquals(20, value); - - value = m_mn.getValue("THIRTY"); - assertEquals(30, value); - } -} diff --git a/test/dorkbox/network/dns/records/NSAP_PTRRecordTest.java b/test/dorkbox/network/dns/records/NSAP_PTRRecordTest.java deleted file mode 100644 index e774b12e..00000000 --- a/test/dorkbox/network/dns/records/NSAP_PTRRecordTest.java +++ /dev/null @@ -1,71 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class NSAP_PTRRecordTest extends TestCase { - public - void test_ctor_0arg() { - NSAP_PTRRecord d = new NSAP_PTRRecord(); - assertNull(d.getName()); - assertNull(d.getTarget()); - } - - public - void test_ctor_4arg() throws TextParseException { - Name n = Name.fromString("my.name."); - Name a = Name.fromString("my.alias."); - - NSAP_PTRRecord d = new NSAP_PTRRecord(n, DnsClass.IN, 0xABCDEL, a); - assertEquals(n, d.getName()); - assertEquals(DnsRecordType.NSAP_PTR, d.getType()); - assertEquals(DnsClass.IN, d.getDClass()); - assertEquals(0xABCDEL, d.getTTL()); - assertEquals(a, d.getTarget()); - } - - public - void test_getObject() { - NSAP_PTRRecord d = new NSAP_PTRRecord(); - DnsRecord r = d.getObject(); - assertTrue(r instanceof NSAP_PTRRecord); - } -} diff --git a/test/dorkbox/network/dns/records/NSRecordTest.java b/test/dorkbox/network/dns/records/NSRecordTest.java deleted file mode 100644 index b6c2c449..00000000 --- a/test/dorkbox/network/dns/records/NSRecordTest.java +++ /dev/null @@ -1,73 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class NSRecordTest extends TestCase { - public - void test_ctor_0arg() { - NSRecord d = new NSRecord(); - assertNull(d.getName()); - assertNull(d.getTarget()); - assertNull(d.getAdditionalName()); - } - - public - void test_ctor_4arg() throws TextParseException { - Name n = Name.fromString("my.name."); - Name a = Name.fromString("my.alias."); - - NSRecord d = new NSRecord(n, DnsClass.IN, 0xABCDEL, a); - assertEquals(n, d.getName()); - assertEquals(DnsRecordType.NS, d.getType()); - assertEquals(DnsClass.IN, d.getDClass()); - assertEquals(0xABCDEL, d.getTTL()); - assertEquals(a, d.getTarget()); - assertEquals(a, d.getAdditionalName()); - } - - public - void test_getObject() { - NSRecord d = new NSRecord(); - DnsRecord r = d.getObject(); - assertTrue(r instanceof NSRecord); - } -} diff --git a/test/dorkbox/network/dns/records/OPTRecordTest.java b/test/dorkbox/network/dns/records/OPTRecordTest.java deleted file mode 100644 index 137fb21d..00000000 --- a/test/dorkbox/network/dns/records/OPTRecordTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package dorkbox.network.dns.records; - -import junit.framework.TestCase; - -public -class OPTRecordTest extends TestCase { - - private static final int DEFAULT_EDNS_RCODE = 0; - private static final int DEFAULT_EDNS_VERSION = 0; - private static final int DEFAULT_PAYLOAD_SIZE = 1024; - - public - void testForNoEqualityWithDifferentEDNS_Versions() { - final OPTRecord optRecordOne = new OPTRecord(DEFAULT_PAYLOAD_SIZE, DEFAULT_EDNS_RCODE, 0); - final OPTRecord optRecordTwo = new OPTRecord(DEFAULT_PAYLOAD_SIZE, DEFAULT_EDNS_RCODE, 1); - assertNotEqual(optRecordOne, optRecordTwo); - } - - private - void assertNotEqual(final OPTRecord optRecordOne, final OPTRecord optRecordTwo) { - assertTrue("Expecting no equality of " + optRecordOne + " compared to " + optRecordTwo, !optRecordOne.equals(optRecordTwo)); - assertTrue("Expecting no equality of " + optRecordTwo + " compared to " + optRecordOne, !optRecordTwo.equals(optRecordOne)); - } - - public - void testForNoEqualityWithDifferentEDNS_RCodes() { - final OPTRecord optRecordOne = new OPTRecord(DEFAULT_PAYLOAD_SIZE, 0, DEFAULT_EDNS_VERSION); - final OPTRecord optRecordTwo = new OPTRecord(DEFAULT_PAYLOAD_SIZE, 1, DEFAULT_EDNS_VERSION); - assertNotEqual(optRecordOne, optRecordTwo); - } - - public - void testForEquality() { - final OPTRecord optRecordOne = new OPTRecord(DEFAULT_PAYLOAD_SIZE, DEFAULT_EDNS_RCODE, DEFAULT_EDNS_VERSION); - final OPTRecord optRecordTwo = new OPTRecord(DEFAULT_PAYLOAD_SIZE, DEFAULT_EDNS_RCODE, DEFAULT_EDNS_VERSION); - assertEquals(optRecordOne, optRecordTwo); - assertEquals(optRecordTwo, optRecordOne); - } -} diff --git a/test/dorkbox/network/dns/records/RRsetTest.java b/test/dorkbox/network/dns/records/RRsetTest.java deleted file mode 100644 index 2b9c0b67..00000000 --- a/test/dorkbox/network/dns/records/RRsetTest.java +++ /dev/null @@ -1,343 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Date; -import java.util.Iterator; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class RRsetTest extends TestCase { - private RRset m_rs; - Name m_name, m_name2; - long m_ttl; - ARecord m_a1, m_a2; - RRSIGRecord m_s1, m_s2; - - @Override - public - void setUp() throws TextParseException, UnknownHostException { - m_rs = new RRset(); - m_name = Name.fromString("this.is.a.test."); - m_name2 = Name.fromString("this.is.another.test."); - m_ttl = 0xABCDL; - m_a1 = new ARecord(m_name, DnsClass.IN, m_ttl, InetAddress.getByName("192.169.232.11")); - m_a2 = new ARecord(m_name, DnsClass.IN, m_ttl + 1, InetAddress.getByName("192.169.232.12")); - - m_s1 = new RRSIGRecord(m_name, - DnsClass.IN, - m_ttl, - DnsRecordType.A, - 0xF, - 0xABCDEL, - new Date(), - new Date(), - 0xA, - m_name, - new byte[0]); - m_s2 = new RRSIGRecord(m_name, - DnsClass.IN, - m_ttl, - DnsRecordType.A, - 0xF, - 0xABCDEL, - new Date(), - new Date(), - 0xA, - m_name2, - new byte[0]); - } - - public - void test_ctor_0arg() { - assertEquals(0, m_rs.size()); - try { - m_rs.getDClass(); - fail("IllegalStateException not thrown"); - } catch (IllegalStateException e) { - } - try { - m_rs.getType(); - fail("IllegalStateException not thrown"); - } catch (IllegalStateException e) { - } - try { - m_rs.getTTL(); - fail("IllegalStateException not thrown"); - } catch (IllegalStateException e) { - } - try { - m_rs.getName(); - fail("IllegalStateException not thrown"); - } catch (IllegalStateException e) { - } - try { - m_rs.first(); - fail("IllegalStateException not thrown"); - } catch (IllegalStateException e) { - } - - assertEquals("{empty}", m_rs.toString()); - - Iterator itr = m_rs.rrs(); - assertNotNull(itr); - assertFalse(itr.hasNext()); - - itr = m_rs.sigs(); - assertNotNull(itr); - assertFalse(itr.hasNext()); - } - - public - void test_basics() throws TextParseException, UnknownHostException { - m_rs.addRR(m_a1); - - assertEquals(1, m_rs.size()); - assertEquals(DnsClass.IN, m_rs.getDClass()); - assertEquals(m_a1, m_rs.first()); - assertEquals(m_name, m_rs.getName()); - assertEquals(m_ttl, m_rs.getTTL()); - assertEquals(DnsRecordType.A, m_rs.getType()); - - // add it again, and make sure nothing changed - m_rs.addRR(m_a1); - - assertEquals(1, m_rs.size()); - assertEquals(DnsClass.IN, m_rs.getDClass()); - assertEquals(m_a1, m_rs.first()); - assertEquals(m_name, m_rs.getName()); - assertEquals(m_ttl, m_rs.getTTL()); - assertEquals(DnsRecordType.A, m_rs.getType()); - - m_rs.addRR(m_a2); - - assertEquals(2, m_rs.size()); - assertEquals(DnsClass.IN, m_rs.getDClass()); - DnsRecord r = m_rs.first(); - assertEquals(m_a1, r); - assertEquals(m_name, m_rs.getName()); - assertEquals(m_ttl, m_rs.getTTL()); - assertEquals(DnsRecordType.A, m_rs.getType()); - - Iterator itr = m_rs.rrs(); - assertEquals(m_a1, itr.next()); - assertEquals(m_a2, itr.next()); - - // make sure that it rotates - itr = m_rs.rrs(); - assertEquals(m_a2, itr.next()); - assertEquals(m_a1, itr.next()); - itr = m_rs.rrs(); - assertEquals(m_a1, itr.next()); - assertEquals(m_a2, itr.next()); - - m_rs.deleteRR(m_a1); - assertEquals(1, m_rs.size()); - assertEquals(DnsClass.IN, m_rs.getDClass()); - assertEquals(m_a2, m_rs.first()); - assertEquals(m_name, m_rs.getName()); - assertEquals(m_ttl, m_rs.getTTL()); - assertEquals(DnsRecordType.A, m_rs.getType()); - - // the signature records - m_rs.addRR(m_s1); - assertEquals(1, m_rs.size()); - itr = m_rs.sigs(); - assertEquals(m_s1, itr.next()); - assertFalse(itr.hasNext()); - - m_rs.addRR(m_s1); - itr = m_rs.sigs(); - assertEquals(m_s1, itr.next()); - assertFalse(itr.hasNext()); - - m_rs.addRR(m_s2); - itr = m_rs.sigs(); - assertEquals(m_s1, itr.next()); - assertEquals(m_s2, itr.next()); - assertFalse(itr.hasNext()); - - m_rs.deleteRR(m_s1); - itr = m_rs.sigs(); - assertEquals(m_s2, itr.next()); - assertFalse(itr.hasNext()); - - - // clear it all - m_rs.clear(); - assertEquals(0, m_rs.size()); - assertFalse(m_rs.rrs() - .hasNext()); - assertFalse(m_rs.sigs() - .hasNext()); - - } - - public - void test_ctor_1arg() { - m_rs.addRR(m_a1); - m_rs.addRR(m_a2); - m_rs.addRR(m_s1); - m_rs.addRR(m_s2); - - RRset rs2 = new RRset(m_rs); - - assertEquals(2, rs2.size()); - assertEquals(m_a1, rs2.first()); - Iterator itr = rs2.rrs(); - assertEquals(m_a1, itr.next()); - assertEquals(m_a2, itr.next()); - assertFalse(itr.hasNext()); - - itr = rs2.sigs(); - assertTrue(itr.hasNext()); - assertEquals(m_s1, itr.next()); - assertTrue(itr.hasNext()); - assertEquals(m_s2, itr.next()); - assertFalse(itr.hasNext()); - } - - public - void test_toString() { - m_rs.addRR(m_a1); - m_rs.addRR(m_a2); - m_rs.addRR(m_s1); - m_rs.addRR(m_s2); - - String out = m_rs.toString(); - - assertTrue(out.indexOf(m_name.toString()) != -1); - assertTrue(out.indexOf(" IN A ") != -1); - assertTrue(out.indexOf("[192.169.232.11]") != -1); - assertTrue(out.indexOf("[192.169.232.12]") != -1); - } - - public - void test_addRR_invalidType() throws TextParseException { - m_rs.addRR(m_a1); - - CNAMERecord c = new CNAMERecord(m_name, DnsClass.IN, m_ttl, Name.fromString("an.alias.")); - - try { - m_rs.addRR(c); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_addRR_invalidName() throws TextParseException, UnknownHostException { - m_rs.addRR(m_a1); - - m_a2 = new ARecord(m_name2, DnsClass.IN, m_ttl, InetAddress.getByName("192.169.232.11")); - - try { - m_rs.addRR(m_a2); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_addRR_invalidDClass() throws TextParseException, UnknownHostException { - m_rs.addRR(m_a1); - - m_a2 = new ARecord(m_name, DnsClass.CHAOS, m_ttl, InetAddress.getByName("192.169.232.11")); - - try { - m_rs.addRR(m_a2); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_TTLcalculation() { - m_rs.addRR(m_a2); - assertEquals(m_a2.getTTL(), m_rs.getTTL()); - m_rs.addRR(m_a1); - assertEquals(m_a1.getTTL(), m_rs.getTTL()); - - Iterator itr = m_rs.rrs(); - while (itr.hasNext()) { - DnsRecord r = (DnsRecord) itr.next(); - assertEquals(m_a1.getTTL(), r.getTTL()); - } - } - - public - void test_Record_placement() { - m_rs.addRR(m_a1); - m_rs.addRR(m_s1); - m_rs.addRR(m_a2); - - Iterator itr = m_rs.rrs(); - assertTrue(itr.hasNext()); - assertEquals(m_a1, itr.next()); - assertTrue(itr.hasNext()); - assertEquals(m_a2, itr.next()); - assertFalse(itr.hasNext()); - - itr = m_rs.sigs(); - assertTrue(itr.hasNext()); - assertEquals(m_s1, itr.next()); - assertFalse(itr.hasNext()); - } - - public - void test_noncycling_iterator() { - m_rs.addRR(m_a1); - m_rs.addRR(m_a2); - - Iterator itr = m_rs.rrs(false); - assertTrue(itr.hasNext()); - assertEquals(m_a1, itr.next()); - assertTrue(itr.hasNext()); - assertEquals(m_a2, itr.next()); - - itr = m_rs.rrs(false); - assertTrue(itr.hasNext()); - assertEquals(m_a1, itr.next()); - assertTrue(itr.hasNext()); - assertEquals(m_a2, itr.next()); - } -} diff --git a/test/dorkbox/network/dns/records/RTRecordTest.java b/test/dorkbox/network/dns/records/RTRecordTest.java deleted file mode 100644 index 12374fca..00000000 --- a/test/dorkbox/network/dns/records/RTRecordTest.java +++ /dev/null @@ -1,65 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class RTRecordTest extends TestCase { - public - void test_getObject() { - RTRecord d = new RTRecord(); - DnsRecord r = d.getObject(); - assertTrue(r instanceof RTRecord); - } - - public - void test_ctor_5arg() throws TextParseException { - Name n = Name.fromString("My.Name."); - Name m = Name.fromString("My.OtherName."); - - RTRecord d = new RTRecord(n, DnsClass.IN, 0xABCDEL, 0xF1, m); - assertEquals(n, d.getName()); - assertEquals(DnsRecordType.RT, d.getType()); - assertEquals(DnsClass.IN, d.getDClass()); - assertEquals(0xABCDEL, d.getTTL()); - assertEquals(0xF1, d.getPreference()); - assertEquals(m, d.getIntermediateHost()); - } -} diff --git a/test/dorkbox/network/dns/records/RecordTest.java b/test/dorkbox/network/dns/records/RecordTest.java deleted file mode 100644 index a3e3def5..00000000 --- a/test/dorkbox/network/dns/records/RecordTest.java +++ /dev/null @@ -1,967 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.Date; - -import dorkbox.network.dns.Compression; -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.exceptions.*; -import dorkbox.network.dns.utils.Options; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.TestCase; - -public -class RecordTest extends TestCase { - private static - class SubRecord extends DnsRecord { - public - SubRecord() {} - - public - SubRecord(Name name, int type, int dclass, long ttl) { - super(name, type, dclass, ttl); - } - - @Override - public - DnsRecord getObject() { - return null; - } - - @Override - public - void rrFromWire(DnsInput in) throws IOException {} - - @Override - public - void rrToWire(DnsOutput out, Compression c, boolean canonical) {} - - @Override - public - void rrToString(StringBuilder sb) { - sb.append("{SubRecord: rrToString}"); - } - - @Override - public - void rdataFromString(Tokenizer t, Name origin) throws IOException {} - - // makes it callable by test code - public static - byte[] byteArrayFromString(String in) throws TextParseException { - return DnsRecord.byteArrayFromString(in); - } - - // make it callable by test code - public static - String byteArrayToString(byte[] in, boolean quote) { - return DnsRecord.byteArrayToString(in, quote); - } - - // make it callable by test code - public static - String unknownToString(byte[] in) { - return DnsRecord.unknownToString(in); - } - - @Override - public - Object clone() throws CloneNotSupportedException { - throw new CloneNotSupportedException(); - } - } - - public - void test_ctor_0arg() { - SubRecord sr = new SubRecord(); - assertNull(sr.getName()); - assertEquals(0, sr.getType()); - assertEquals(0, sr.getTTL()); - assertEquals(0, sr.getDClass()); - } - - public - void test_ctor_4arg() throws TextParseException { - Name n = Name.fromString("my.name."); - int t = DnsRecordType.A; - int d = DnsClass.IN; - long ttl = 0xABCDEL; - - SubRecord r = new SubRecord(n, t, d, ttl); - assertEquals(n, r.getName()); - assertEquals(t, r.getType()); - assertEquals(d, r.getDClass()); - assertEquals(ttl, r.getTTL()); - } - - public - void test_ctor_4arg_invalid() throws TextParseException { - Name n = Name.fromString("my.name."); - Name r = Name.fromString("my.relative.name"); - int t = DnsRecordType.A; - int d = DnsClass.IN; - long ttl = 0xABCDEL; - - try { - new SubRecord(r, t, d, ttl); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException ignored) { - } - - try { - new SubRecord(n, -1, d, ttl); - fail("InvalidTypeException not thrown"); - } catch (InvalidTypeException ignored) { - } - - try { - new SubRecord(n, t, -1, ttl); - fail("InvalidDClassException not thrown"); - } catch (InvalidDClassException ignored) { - } - - try { - new SubRecord(n, t, d, -1); - fail("InvalidTTLException not thrown"); - } catch (InvalidTTLException ignored) { - } - } - - public - void test_newRecord_3arg() throws TextParseException { - Name n = Name.fromString("my.name."); - Name r = Name.fromString("my.relative.name"); - int t = DnsRecordType.A; - int d = DnsClass.IN; - - DnsRecord rec = DnsRecord.newRecord(n, t, d); - assertTrue(rec instanceof EmptyRecord); - assertEquals(n, rec.getName()); - assertEquals(t, rec.getType()); - assertEquals(d, rec.getDClass()); - assertEquals(0, rec.getTTL()); - - try { - DnsRecord.newRecord(r, t, d); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException ignored) { - } - } - - public - void test_newRecord_4arg() throws TextParseException { - Name n = Name.fromString("my.name."); - Name r = Name.fromString("my.relative.name"); - int t = DnsRecordType.A; - int d = DnsClass.IN; - int ttl = 0xDBE8; - - DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl); - assertTrue(rec instanceof EmptyRecord); - assertEquals(n, rec.getName()); - assertEquals(t, rec.getType()); - assertEquals(d, rec.getDClass()); - assertEquals(ttl, rec.getTTL()); - - try { - DnsRecord.newRecord(r, t, d, ttl); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException ignored) { - } - } - - public - void test_newRecord_5arg() throws TextParseException, UnknownHostException { - Name n = Name.fromString("my.name."); - int t = DnsRecordType.A; - int d = DnsClass.IN; - int ttl = 0xDBE8; - byte[] data = new byte[] {(byte) 123, (byte) 232, (byte) 0, (byte) 255}; - InetAddress exp = InetAddress.getByName("123.232.0.255"); - - DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl, data); - assertTrue(rec instanceof ARecord); - assertEquals(n, rec.getName()); - assertEquals(t, rec.getType()); - assertEquals(d, rec.getDClass()); - assertEquals(ttl, rec.getTTL()); - assertEquals(exp, ((ARecord) rec).getAddress()); - } - - public - void test_newRecord_6arg() throws TextParseException, UnknownHostException { - Name n = Name.fromString("my.name."); - int t = DnsRecordType.A; - int d = DnsClass.IN; - int ttl = 0xDBE8; - byte[] data = new byte[] {(byte) 123, (byte) 232, (byte) 0, (byte) 255}; - InetAddress exp = InetAddress.getByName("123.232.0.255"); - - DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl, 0, null); - assertTrue(rec instanceof EmptyRecord); - assertEquals(n, rec.getName()); - assertEquals(t, rec.getType()); - assertEquals(d, rec.getDClass()); - assertEquals(ttl, rec.getTTL()); - - rec = DnsRecord.newRecord(n, t, d, ttl, data.length, data); - assertTrue(rec instanceof ARecord); - assertEquals(n, rec.getName()); - assertEquals(t, rec.getType()); - assertEquals(d, rec.getDClass()); - assertEquals(ttl, rec.getTTL()); - assertEquals(exp, ((ARecord) rec).getAddress()); - - rec = DnsRecord.newRecord(n, DnsRecordType.NIMLOC, d, ttl, data.length, data); - assertTrue(rec instanceof UNKRecord); - assertEquals(n, rec.getName()); - assertEquals(DnsRecordType.NIMLOC, rec.getType()); - assertEquals(d, rec.getDClass()); - assertEquals(ttl, rec.getTTL()); - assertTrue(Arrays.equals(data, ((UNKRecord) rec).getData())); - } - - public - void test_newRecord_6arg_invalid() throws TextParseException { - Name n = Name.fromString("my.name."); - Name r = Name.fromString("my.relative.name"); - int t = DnsRecordType.A; - int d = DnsClass.IN; - int ttl = 0xDBE8; - byte[] data = new byte[] {(byte) 123, (byte) 232, (byte) 0, (byte) 255}; - - assertNull(DnsRecord.newRecord(n, t, d, ttl, 0, new byte[0])); - assertNull(DnsRecord.newRecord(n, t, d, ttl, 1, new byte[0])); - assertNull(DnsRecord.newRecord(n, t, d, ttl, data.length + 1, data)); - assertNull(DnsRecord.newRecord(n, t, d, ttl, 5, new byte[] {data[0], data[1], data[2], data[3], 0})); - try { - DnsRecord.newRecord(r, t, d, ttl, 0, null); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException ignored) { - } - - } - - public - void test_fromWire() throws IOException, TextParseException, UnknownHostException { - Name n = Name.fromString("my.name."); - int t = DnsRecordType.A; - int d = DnsClass.IN; - int ttl = 0xDBE8; - byte[] data = new byte[] {(byte) 123, (byte) 232, (byte) 0, (byte) 255}; - InetAddress exp = InetAddress.getByName("123.232.0.255"); - - DnsOutput out = new DnsOutput(); - n.toWire(out, null); - out.writeU16(t); - out.writeU16(d); - out.writeU32(ttl); - out.writeU16(data.length); - out.writeByteArray(data); - - byte[] bytes = out.toByteArray(); - DnsInput in = new DnsInput(bytes); - - DnsRecord rec = DnsRecord.fromWire(in, DnsSection.ANSWER, false); - assertTrue(rec instanceof ARecord); - assertEquals(n, rec.getName()); - assertEquals(t, rec.getType()); - assertEquals(d, rec.getDClass()); - assertEquals(ttl, rec.getTTL()); - assertEquals(exp, ((ARecord) rec).getAddress()); - - in = new DnsInput(bytes); - rec = DnsRecord.fromWire(in, DnsSection.QUESTION, false); - assertTrue(rec instanceof EmptyRecord); - assertEquals(n, rec.getName()); - assertEquals(t, rec.getType()); - assertEquals(d, rec.getDClass()); - assertEquals(0, rec.getTTL()); - - in = new DnsInput(bytes); - rec = DnsRecord.fromWire(in, DnsSection.QUESTION); - assertTrue(rec instanceof EmptyRecord); - assertEquals(n, rec.getName()); - assertEquals(t, rec.getType()); - assertEquals(d, rec.getDClass()); - assertEquals(0, rec.getTTL()); - - rec = DnsRecord.fromWire(bytes, DnsSection.QUESTION); - assertTrue(rec instanceof EmptyRecord); - assertEquals(n, rec.getName()); - assertEquals(t, rec.getType()); - assertEquals(d, rec.getDClass()); - assertEquals(0, rec.getTTL()); - - out = new DnsOutput(); - n.toWire(out, null); - out.writeU16(t); - out.writeU16(d); - out.writeU32(ttl); - out.writeU16(0); - - in = new DnsInput(out.toByteArray()); - - rec = DnsRecord.fromWire(in, DnsSection.ANSWER, true); - assertTrue(rec instanceof EmptyRecord); - assertEquals(n, rec.getName()); - assertEquals(t, rec.getType()); - assertEquals(d, rec.getDClass()); - assertEquals(ttl, rec.getTTL()); - - } - - public - void test_toWire() throws IOException, TextParseException, UnknownHostException - - { - Name n = Name.fromString("my.name."); - int t = DnsRecordType.A; - int d = DnsClass.IN; - int ttl = 0xDBE8; - byte[] data = new byte[] {(byte) 123, (byte) 232, (byte) 0, (byte) 255}; - - // a non-QUESTION - DnsOutput out = new DnsOutput(); - n.toWire(out, null); - out.writeU16(t); - out.writeU16(d); - out.writeU32(ttl); - out.writeU16(data.length); - out.writeByteArray(data); - - byte[] exp = out.toByteArray(); - - DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl, data.length, data); - - out = new DnsOutput(); - - rec.toWire(out, DnsSection.ANSWER, null); - - byte[] after = out.toByteArray(); - - assertTrue(Arrays.equals(exp, after)); - - // an equivalent call - after = rec.toWire(DnsSection.ANSWER); - assertTrue(Arrays.equals(exp, after)); - - // a QUESTION entry - out = new DnsOutput(); - n.toWire(out, null); - out.writeU16(t); - out.writeU16(d); - - exp = out.toByteArray(); - out = new DnsOutput(); - rec.toWire(out, DnsSection.QUESTION, null); - after = out.toByteArray(); - - assertTrue(Arrays.equals(exp, after)); - - } - - public - void test_toWireCanonical() throws IOException, TextParseException, UnknownHostException - - { - Name n = Name.fromString("My.Name."); - int t = DnsRecordType.A; - int d = DnsClass.IN; - int ttl = 0xDBE8; - byte[] data = new byte[] {(byte) 123, (byte) 232, (byte) 0, (byte) 255}; - - DnsOutput out = new DnsOutput(); - n.toWireCanonical(out); - out.writeU16(t); - out.writeU16(d); - out.writeU32(ttl); - out.writeU16(data.length); - out.writeByteArray(data); - - byte[] exp = out.toByteArray(); - - DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl, data.length, data); - - byte[] after = rec.toWireCanonical(); - assertTrue(Arrays.equals(exp, after)); - } - - public - void test_rdataToWireCanonical() throws IOException, TextParseException, UnknownHostException - - { - Name n = Name.fromString("My.Name."); - Name n2 = Name.fromString("My.Second.Name."); - int t = DnsRecordType.NS; - int d = DnsClass.IN; - int ttl = 0xABE99; - DnsOutput out = new DnsOutput(); - n2.toWire(out, null); - byte[] data = out.toByteArray(); - - out = new DnsOutput(); - n2.toWireCanonical(out); - byte[] exp = out.toByteArray(); - - DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl, data.length, data); - assertTrue(rec instanceof NSRecord); - - byte[] after = rec.rdataToWireCanonical(); - - assertTrue(Arrays.equals(exp, after)); - } - - public - void test_rdataToString() throws IOException, TextParseException, UnknownHostException - - { - Name n = Name.fromString("My.Name."); - Name n2 = Name.fromString("My.Second.Name."); - int t = DnsRecordType.NS; - int d = DnsClass.IN; - int ttl = 0xABE99; - DnsOutput out = new DnsOutput(); - n2.toWire(out, null); - byte[] data = out.toByteArray(); - - DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl, data.length, data); - assertTrue(rec instanceof NSRecord); - StringBuilder sa = new StringBuilder(); - rec.rrToString(sa); - - StringBuilder sb = new StringBuilder(); - rec.rdataToString(sb); - - assertEquals(sa.toString(), sb.toString()); - } - - public - void test_toString() throws TextParseException { - Name n = Name.fromString("My.N."); - Name n2 = Name.fromString("My.Second.Name."); - int t = DnsRecordType.NS; - int d = DnsClass.IN; - int ttl = 0xABE99; - DnsOutput o = new DnsOutput(); - n2.toWire(o, null); - byte[] data = o.toByteArray(); - - DnsRecord rec = DnsRecord.newRecord(n, t, d, ttl, data.length, data); - String out = rec.toString(); - - assertFalse(out.indexOf(n.toString()) == -1); - assertFalse(out.indexOf(n2.toString()) == -1); - assertFalse(out.indexOf("NS") == -1); - assertFalse(out.indexOf("IN") == -1); - assertFalse(out.indexOf(ttl + "") == -1); - - Options.set("BINDTTL"); - - out = rec.toString(); - assertFalse(out.indexOf(n.toString()) == -1); - assertFalse(out.indexOf(n2.toString()) == -1); - assertFalse(out.indexOf("NS") == -1); - assertFalse(out.indexOf("IN") == -1); - assertFalse(out.indexOf(TTL.format(ttl)) == -1); - - Options.set("noPrintIN"); - out = rec.toString(); - assertFalse(out.indexOf(n.toString()) == -1); - assertFalse(out.indexOf(n2.toString()) == -1); - assertFalse(out.indexOf("NS") == -1); - assertTrue(out.indexOf("IN") == -1); - assertFalse(out.indexOf(TTL.format(ttl)) == -1); - } - - public - void test_byteArrayFromString() throws TextParseException { - String in = "the 98 \" \' quick 0xAB brown"; - byte[] out = SubRecord.byteArrayFromString(in); - assertTrue(Arrays.equals(in.getBytes(), out)); - - in = " \\031Aa\\;\\\"\\\\~\\127\\255"; - byte[] exp = new byte[] {' ', 0x1F, 'A', 'a', ';', '"', '\\', 0x7E, 0x7F, (byte) 0xFF}; - out = SubRecord.byteArrayFromString(in); - assertTrue(Arrays.equals(exp, out)); - } - - public - void test_byteArrayFromString_invalid() { - StringBuilder b = new StringBuilder(); - for (int i = 0; i < 257; ++i) { - b.append('A'); - } - try { - SubRecord.byteArrayFromString(b.toString()); - fail("TextParseException not thrown"); - } catch (TextParseException ignored) { - } - - try { - SubRecord.byteArrayFromString("\\256"); - fail("TextParseException not thrown"); - } catch (TextParseException ignored) { - } - try { - SubRecord.byteArrayFromString("\\25a"); - fail("TextParseException not thrown"); - } catch (TextParseException ignored) { - } - try { - SubRecord.byteArrayFromString("\\25"); - fail("TextParseException not thrown"); - } catch (TextParseException ignored) { - } - - b.append("\\233"); - try { - SubRecord.byteArrayFromString(b.toString()); - fail("TextParseException not thrown"); - } catch (TextParseException ignored) { - } - - } - - public - void test_byteArrayToString() { - byte[] in = new byte[] {' ', 0x1F, 'A', 'a', ';', '"', '\\', 0x7E, 0x7F, (byte) 0xFF}; - String exp = "\" \\031Aa;\\\"\\\\~\\127\\255\""; - assertEquals(exp, SubRecord.byteArrayToString(in, true)); - } - - public - void test_unknownToString() { - byte[] data = new byte[] {(byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x9A, (byte) 0xBC, (byte) 0xDE, (byte) 0xFF}; - String out = SubRecord.unknownToString(data); - - assertFalse(out.indexOf("" + data.length) == -1); - assertFalse(out.indexOf("123456789ABCDEFF") == -1); - } - - public - void test_fromString() throws IOException, TextParseException { - Name n = Name.fromString("My.N."); - Name n2 = Name.fromString("My.Second.Name."); - int t = DnsRecordType.A; - int d = DnsClass.IN; - int ttl = 0xABE99; - String sa = "191.234.43.10"; - InetAddress addr = InetAddress.getByName(sa); - byte[] b = new byte[] {(byte) 191, (byte) 234, (byte) 43, (byte) 10}; - - Tokenizer st = new Tokenizer(sa); - DnsRecord rec = DnsRecord.fromString(n, t, d, ttl, st, n2); - assertTrue(rec instanceof ARecord); - assertEquals(n, rec.getName()); - assertEquals(t, rec.getType()); - assertEquals(d, rec.getDClass()); - assertEquals(ttl, rec.getTTL()); - assertEquals(addr, ((ARecord) rec).getAddress()); - - String unkData = SubRecord.unknownToString(b); - st = new Tokenizer(unkData); - rec = DnsRecord.fromString(n, t, d, ttl, st, n2); - assertTrue(rec instanceof ARecord); - assertEquals(n, rec.getName()); - assertEquals(t, rec.getType()); - assertEquals(d, rec.getDClass()); - assertEquals(ttl, rec.getTTL()); - assertEquals(addr, ((ARecord) rec).getAddress()); - } - - public - void test_fromString_invalid() throws IOException, TextParseException { - Name n = Name.fromString("My.N."); - Name rel = Name.fromString("My.R"); - Name n2 = Name.fromString("My.Second.Name."); - int t = DnsRecordType.A; - int d = DnsClass.IN; - int ttl = 0xABE99; - InetAddress addr = InetAddress.getByName("191.234.43.10"); - - Tokenizer st = new Tokenizer("191.234.43.10"); - - try { - DnsRecord.fromString(rel, t, d, ttl, st, n2); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException ignored) { - } - - st = new Tokenizer("191.234.43.10 another_token"); - try { - DnsRecord.fromString(n, t, d, ttl, st, n2); - fail("TextParseException not thrown"); - } catch (TextParseException ignored) { - } - - st = new Tokenizer("\\# 100 ABCDE"); - try { - DnsRecord.fromString(n, t, d, ttl, st, n2); - fail("TextParseException not thrown"); - } catch (TextParseException ignored) { - } - - try { - DnsRecord.fromString(n, t, d, ttl, "\\# 100", n2); - fail("TextParseException not thrown"); - } catch (TextParseException ignored) { - } - } - - public - void test_getRRsetType() throws TextParseException { - Name n = Name.fromString("My.N."); - - DnsRecord r = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0); - assertEquals(DnsRecordType.A, r.getRRsetType()); - - r = new RRSIGRecord(n, DnsClass.IN, 0, DnsRecordType.A, 1, 0, new Date(), new Date(), 10, n, new byte[0]); - assertEquals(DnsRecordType.A, r.getRRsetType()); - } - - public - void test_sameRRset() throws TextParseException { - Name n = Name.fromString("My.N."); - Name m = Name.fromString("My.M."); - - DnsRecord r1 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0); - DnsRecord r2 = new RRSIGRecord(n, DnsClass.IN, 0, DnsRecordType.A, 1, 0, new Date(), new Date(), 10, n, new byte[0]); - assertTrue(r1.sameRRset(r2)); - assertTrue(r2.sameRRset(r1)); - - r1 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.HS, 0); - r2 = new RRSIGRecord(n, DnsClass.IN, 0, DnsRecordType.A, 1, 0, new Date(), new Date(), 10, n, new byte[0]); - assertFalse(r1.sameRRset(r2)); - assertFalse(r2.sameRRset(r1)); - - r1 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0); - r2 = new RRSIGRecord(m, DnsClass.IN, 0, DnsRecordType.A, 1, 0, new Date(), new Date(), 10, n, new byte[0]); - assertFalse(r1.sameRRset(r2)); - assertFalse(r2.sameRRset(r1)); - } - - public - void test_equals() throws TextParseException { - Name n = Name.fromString("My.N."); - Name n2 = Name.fromString("my.n."); - Name m = Name.fromString("My.M."); - - DnsRecord r1 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0); - - assertFalse(r1.equals(null)); - assertFalse(r1.equals(new Object())); - - DnsRecord r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0); - assertEquals(r1, r2); - assertEquals(r2, r1); - - r2 = DnsRecord.newRecord(n2, DnsRecordType.A, DnsClass.IN, 0); - assertEquals(r1, r2); - assertEquals(r2, r1); - - r2 = DnsRecord.newRecord(n2, DnsRecordType.A, DnsClass.IN, 0xABCDE); - assertEquals(r1, r2); - assertEquals(r2, r1); - - r2 = DnsRecord.newRecord(m, DnsRecordType.A, DnsClass.IN, 0xABCDE); - assertFalse(r1.equals(r2)); - assertFalse(r2.equals(r1)); - - r2 = DnsRecord.newRecord(n2, DnsRecordType.MX, DnsClass.IN, 0xABCDE); - assertFalse(r1.equals(r2)); - assertFalse(r2.equals(r1)); - - r2 = DnsRecord.newRecord(n2, DnsRecordType.A, DnsClass.CHAOS, 0xABCDE); - assertFalse(r1.equals(r2)); - assertFalse(r2.equals(r1)); - - byte[] d1 = new byte[] {23, 12, 9, (byte) 129}; - byte[] d2 = new byte[] {(byte) 220, 1, (byte) 131, (byte) 212}; - - r1 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d1); - r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d1); - - assertEquals(r1, r2); - assertEquals(r2, r1); - - r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d2); - - assertFalse(r1.equals(r2)); - assertFalse(r2.equals(r1)); - } - - public - void test_hashCode() throws TextParseException { - Name n = Name.fromString("My.N."); - Name n2 = Name.fromString("my.n."); - Name m = Name.fromString("My.M."); - byte[] d1 = new byte[] {23, 12, 9, (byte) 129}; - byte[] d2 = new byte[] {(byte) 220, 1, (byte) 131, (byte) 212}; - - DnsRecord r1 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d1); - - // same DnsDnsRecord has same hash code - DnsRecord r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d1); - assertEquals(r1.hashCode(), r2.hashCode()); - - // case of names should not matter - r2 = DnsRecord.newRecord(n2, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d1); - assertEquals(r1.hashCode(), r2.hashCode()); - - // different names - r2 = DnsRecord.newRecord(m, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d1); - assertFalse(r1.hashCode() == r2.hashCode()); - - // different class - r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.CHAOS, 0xABCDE9, d1); - assertFalse(r1.hashCode() == r2.hashCode()); - - // different TTL does not matter - r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE, d1); - assertEquals(r1.hashCode(), r2.hashCode()); - - // different data - r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d2); - assertFalse(r1.hashCode() == r2.hashCode()); - } - - public - void test_cloneRecord() throws TextParseException { - Name n = Name.fromString("My.N."); - byte[] d = new byte[] {23, 12, 9, (byte) 129}; - DnsRecord r = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); - - DnsRecord r2 = r.cloneRecord(); - - assertNotSame(r, r2); - assertEquals(r, r2); - - r = new SubRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9); - - try { - r.cloneRecord(); - fail("IllegalStateException not thrown"); - } catch (IllegalStateException ignored) { - } - } - - public - void test_withName() throws TextParseException { - Name n = Name.fromString("My.N."); - Name m = Name.fromString("My.M.Name."); - Name rel = Name.fromString("My.Relative.Name"); - byte[] d = new byte[] {23, 12, 9, (byte) 129}; - DnsRecord r = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); - - DnsRecord r1 = r.withName(m); - - assertEquals(m, r1.getName()); - assertEquals(DnsRecordType.A, r1.getType()); - assertEquals(DnsClass.IN, r1.getDClass()); - assertEquals(0xABCDE9, r1.getTTL()); - assertEquals(((ARecord) r).getAddress(), ((ARecord) r1).getAddress()); - - try { - r.withName(rel); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException ignored) { - } - } - - public - void test_withDClass() throws TextParseException { - Name n = Name.fromString("My.N."); - byte[] d = new byte[] {23, 12, 9, (byte) 129}; - DnsRecord r = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); - - DnsRecord r1 = r.withDClass(DnsClass.HESIOD, 0x9876); - - assertEquals(n, r1.getName()); - assertEquals(DnsRecordType.A, r1.getType()); - assertEquals(DnsClass.HESIOD, r1.getDClass()); - assertEquals(0x9876, r1.getTTL()); - assertEquals(((ARecord) r).getAddress(), ((ARecord) r1).getAddress()); - } - - public - void test_setTTL() throws TextParseException, UnknownHostException { - Name n = Name.fromString("My.N."); - byte[] d = new byte[] {23, 12, 9, (byte) 129}; - InetAddress exp = InetAddress.getByName("23.12.9.129"); - DnsRecord r = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); - - assertEquals(0xABCDE9, r.getTTL()); - - r.setTTL(0x9876); - - assertEquals(n, r.getName()); - assertEquals(DnsRecordType.A, r.getType()); - assertEquals(DnsClass.IN, r.getDClass()); - assertEquals(0x9876, r.getTTL()); - assertEquals(exp, ((ARecord) r).getAddress()); - } - - public - void test_compareTo() throws TextParseException { - Name n = Name.fromString("My.N."); - Name n2 = Name.fromString("my.n."); - Name m = Name.fromString("My.M."); - byte[] d = new byte[] {23, 12, 9, (byte) 129}; - byte[] d2 = new byte[] {23, 12, 9, (byte) 128}; - DnsRecord r1 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); - DnsRecord r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); - - assertEquals(0, r1.compareTo(r1)); - - assertEquals(0, r1.compareTo(r2)); - assertEquals(0, r2.compareTo(r1)); - - // name comparison should be canonical - r2 = DnsRecord.newRecord(n2, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); - assertEquals(0, r1.compareTo(r2)); - assertEquals(0, r2.compareTo(r1)); - - // different name - r2 = DnsRecord.newRecord(m, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d); - assertEquals(n.compareTo(m), r1.compareTo(r2)); - assertEquals(m.compareTo(n), r2.compareTo(r1)); - - // different DnsClass - r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.CHAOS, 0xABCDE9, d); - assertEquals(DnsClass.IN - DnsClass.CHAOS, r1.compareTo(r2)); - assertEquals(DnsClass.CHAOS - DnsClass.IN, r2.compareTo(r1)); - - // different DnsRecordType - r2 = DnsRecord.newRecord(n, DnsRecordType.NS, DnsClass.IN, 0xABCDE9, m.toWire()); - assertEquals(DnsRecordType.A - DnsRecordType.NS, r1.compareTo(r2)); - assertEquals(DnsRecordType.NS - DnsRecordType.A, r2.compareTo(r1)); - - // different data (same length) - r2 = DnsRecord.newRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9, d2); - assertEquals(1, r1.compareTo(r2)); - assertEquals(-1, r2.compareTo(r1)); - - // different data (one a prefix of the other) - m = Name.fromString("My.N.L."); - r1 = DnsRecord.newRecord(n, DnsRecordType.NS, DnsClass.IN, 0xABCDE9, n.toWire()); - r2 = DnsRecord.newRecord(n, DnsRecordType.NS, DnsClass.IN, 0xABCDE9, m.toWire()); - assertEquals(-1, r1.compareTo(r2)); - assertEquals(1, r2.compareTo(r1)); - } - - public - void test_getAdditionalName() throws TextParseException { - Name n = Name.fromString("My.N."); - DnsRecord r = new SubRecord(n, DnsRecordType.A, DnsClass.IN, 0xABCDE9); - - assertNull(r.getAdditionalName()); - } - - public - void test_checkU8() { - try { - DnsRecord.checkU8("field", -1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - assertEquals(0, DnsRecord.checkU8("field", 0)); - assertEquals(0x9D, DnsRecord.checkU8("field", 0x9D)); - assertEquals(0xFF, DnsRecord.checkU8("field", 0xFF)); - try { - DnsRecord.checkU8("field", 0x100); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_checkU16() { - try { - DnsRecord.checkU16("field", -1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - assertEquals(0, DnsRecord.checkU16("field", 0)); - assertEquals(0x9DA1, DnsRecord.checkU16("field", 0x9DA1)); - assertEquals(0xFFFF, DnsRecord.checkU16("field", 0xFFFF)); - try { - DnsRecord.checkU16("field", 0x10000); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_checkU32() { - try { - DnsRecord.checkU32("field", -1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - assertEquals(0, DnsRecord.checkU32("field", 0)); - assertEquals(0x9DA1F02DL, DnsRecord.checkU32("field", 0x9DA1F02DL)); - assertEquals(0xFFFFFFFFL, DnsRecord.checkU32("field", 0xFFFFFFFFL)); - try { - DnsRecord.checkU32("field", 0x100000000L); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_checkName() throws TextParseException { - Name n = Name.fromString("My.N."); - Name m = Name.fromString("My.m"); - - assertEquals(n, DnsRecord.checkName("field", n)); - - try { - DnsRecord.checkName("field", m); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException ignored) { - } - } -} diff --git a/test/dorkbox/network/dns/records/SOARecordTest.java b/test/dorkbox/network/dns/records/SOARecordTest.java deleted file mode 100644 index 8459d8fe..00000000 --- a/test/dorkbox/network/dns/records/SOARecordTest.java +++ /dev/null @@ -1,455 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.Random; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.RelativeNameException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Options; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -public -class SOARecordTest { - private final static Random m_random = new Random(); - - private static - long randomU16() { - return m_random.nextLong() >>> 48; - } - - private static - long randomU32() { - return m_random.nextLong() >>> 32; - } - - public static - class Test_init extends TestCase { - private Name m_an, m_rn, m_host, m_admin; - private long m_ttl, m_serial, m_refresh, m_retry, m_expire, m_minimum; - - @Override - protected - void setUp() throws TextParseException, UnknownHostException { - m_an = Name.fromString("My.Absolute.Name."); - m_rn = Name.fromString("My.Relative.Name"); - m_host = Name.fromString("My.Host.Name."); - m_admin = Name.fromString("My.Administrative.Name."); - m_ttl = randomU16(); - m_serial = randomU32(); - m_refresh = randomU32(); - m_retry = randomU32(); - m_expire = randomU32(); - m_minimum = randomU32(); - } - - public - void test_0arg() throws UnknownHostException { - SOARecord ar = new SOARecord(); - assertNull(ar.getName()); - assertEquals(0, ar.getType()); - assertEquals(0, ar.getDClass()); - assertEquals(0, ar.getTTL()); - assertNull(ar.getHost()); - assertNull(ar.getAdmin()); - assertEquals(0, ar.getSerial()); - assertEquals(0, ar.getRefresh()); - assertEquals(0, ar.getRetry()); - assertEquals(0, ar.getExpire()); - assertEquals(0, ar.getMinimum()); - } - - public - void test_getObject() { - SOARecord ar = new SOARecord(); - DnsRecord r = ar.getObject(); - assertTrue(r instanceof SOARecord); - } - - public - void test_10arg() { - SOARecord ar = new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, m_minimum); - assertEquals(m_an, ar.getName()); - assertEquals(DnsRecordType.SOA, ar.getType()); - assertEquals(DnsClass.IN, ar.getDClass()); - assertEquals(m_ttl, ar.getTTL()); - assertEquals(m_host, ar.getHost()); - assertEquals(m_admin, ar.getAdmin()); - assertEquals(m_serial, ar.getSerial()); - assertEquals(m_refresh, ar.getRefresh()); - assertEquals(m_retry, ar.getRetry()); - assertEquals(m_expire, ar.getExpire()); - assertEquals(m_minimum, ar.getMinimum()); - } - - public - void test_10arg_relative_name() { - try { - new SOARecord(m_rn, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, m_minimum); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException ignored) { - } - } - - public - void test_10arg_relative_host() { - try { - new SOARecord(m_an, DnsClass.IN, m_ttl, m_rn, m_admin, m_serial, m_refresh, m_retry, m_expire, m_minimum); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException ignored) { - } - } - - public - void test_10arg_relative_admin() { - try { - new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_rn, m_serial, m_refresh, m_retry, m_expire, m_minimum); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException ignored) { - } - } - - public - void test_10arg_negative_serial() { - try { - new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, -1, m_refresh, m_retry, m_expire, m_minimum); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_10arg_toobig_serial() { - try { - new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, 0x100000000L, m_refresh, m_retry, m_expire, m_minimum); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_10arg_negative_refresh() { - try { - new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, -1, m_retry, m_expire, m_minimum); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_10arg_toobig_refresh() { - try { - new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, 0x100000000L, m_retry, m_expire, m_minimum); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_10arg_negative_retry() { - try { - new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, -1, m_expire, m_minimum); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_10arg_toobig_retry() { - try { - new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, 0x100000000L, m_expire, m_minimum); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_10arg_negative_expire() { - try { - new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, -1, m_minimum); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_10arg_toobig_expire() { - try { - new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, 0x100000000L, m_minimum); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_10arg_negative_minimun() { - try { - new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, -1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - - public - void test_10arg_toobig_minimum() { - try { - new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, 0x100000000L); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException ignored) { - } - } - } - - - public static - class Test_rrFromWire extends TestCase { - private Name m_host, m_admin; - private long m_serial, m_refresh, m_retry, m_expire, m_minimum; - - public - void test() throws IOException { - byte[] raw = new byte[] {1, 'm', 1, 'h', 1, 'n', 0, // host - 1, 'm', 1, 'a', 1, 'n', 0, // admin - (byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x12, // serial - (byte) 0xCD, (byte) 0xEF, (byte) 0x12, (byte) 0x34, // refresh - (byte) 0xEF, (byte) 0x12, (byte) 0x34, (byte) 0x56, // retry - (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, // expire - (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x9A}; // minimum - - DnsInput di = new DnsInput(raw); - SOARecord ar = new SOARecord(); - - ar.rrFromWire(di); - - assertEquals(m_host, ar.getHost()); - assertEquals(m_admin, ar.getAdmin()); - assertEquals(m_serial, ar.getSerial()); - assertEquals(m_refresh, ar.getRefresh()); - assertEquals(m_retry, ar.getRetry()); - assertEquals(m_expire, ar.getExpire()); - assertEquals(m_minimum, ar.getMinimum()); - } @Override - protected - void setUp() throws TextParseException, UnknownHostException { - m_host = Name.fromString("M.h.N."); - m_admin = Name.fromString("M.a.n."); - m_serial = 0xABCDEF12L; - m_refresh = 0xCDEF1234L; - m_retry = 0xEF123456L; - m_expire = 0x12345678L; - m_minimum = 0x3456789AL; - } - - - } - - - public static - class Test_rdataFromString extends TestCase { - private Name m_host, m_admin, m_origin; - private long m_serial, m_refresh, m_retry, m_expire, m_minimum; - - public - void test_valid() throws IOException { - Tokenizer t = new Tokenizer("M.h " + m_admin + " " + m_serial + " " + m_refresh + " " + m_retry + " " + m_expire + " " + - m_minimum); - SOARecord ar = new SOARecord(); - - ar.rdataFromString(t, m_origin); - - assertEquals(m_host, ar.getHost()); - assertEquals(m_admin, ar.getAdmin()); - assertEquals(m_serial, ar.getSerial()); - assertEquals(m_refresh, ar.getRefresh()); - assertEquals(m_retry, ar.getRetry()); - assertEquals(m_expire, ar.getExpire()); - assertEquals(m_minimum, ar.getMinimum()); - } @Override - protected - void setUp() throws TextParseException, UnknownHostException { - m_origin = Name.fromString("O."); - m_host = Name.fromString("M.h", m_origin); - m_admin = Name.fromString("M.a.n."); - m_serial = 0xABCDEF12L; - m_refresh = 0xCDEF1234L; - m_retry = 0xEF123456L; - m_expire = 0x12345678L; - m_minimum = 0x3456789AL; - } - - public - void test_relative_name() throws IOException { - Tokenizer t = new Tokenizer("M.h " + m_admin + " " + m_serial + " " + m_refresh + " " + m_retry + " " + m_expire + " " + - m_minimum); - SOARecord ar = new SOARecord(); - - try { - ar.rdataFromString(t, null); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException ignored) { - } - } - - - } - - - public static - class Test_rrToString extends TestCase { - private Name m_an, m_host, m_admin; - private long m_ttl, m_serial, m_refresh, m_retry, m_expire, m_minimum; - - public - void test_singleLine() { - SOARecord ar = new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, m_minimum); - String exp = m_host + " " + m_admin + " " + m_serial + " " + m_refresh + " " + m_retry + " " + m_expire + " " + m_minimum; - - StringBuilder sb = new StringBuilder(); - ar.rrToString(sb); - String out = sb.toString(); - - assertEquals(exp, out); - } @Override - protected - void setUp() throws TextParseException { - m_an = Name.fromString("My.absolute.name."); - m_ttl = 0x13A8; - m_host = Name.fromString("M.h.N."); - m_admin = Name.fromString("M.a.n."); - m_serial = 0xABCDEF12L; - m_refresh = 0xCDEF1234L; - m_retry = 0xEF123456L; - m_expire = 0x12345678L; - m_minimum = 0x3456789AL; - } - - public - void test_multiLine() { - SOARecord ar = new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, m_minimum); - String re = "^.*\\(\\n" + "\\s*" + m_serial + "\\s*;\\s*serial\\n" + // serial - "\\s*" + m_refresh + "\\s*;\\s*refresh\\n" + // refresh - "\\s*" + m_retry + "\\s*;\\s*retry\\n" + // retry - "\\s*" + m_expire + "\\s*;\\s*expire\\n" + // expire - "\\s*" + m_minimum + "\\s*\\)\\s*;\\s*minimum$"; // minimum - - Options.set("multiline"); - StringBuilder sb = new StringBuilder(); - ar.rrToString(sb); - String out = sb.toString(); - Options.unset("multiline"); - - assertTrue(out.matches(re)); - } - - - } - - - public static - class Test_rrToWire extends TestCase { - private Name m_an, m_host, m_admin; - private long m_ttl, m_serial, m_refresh, m_retry, m_expire, m_minimum; - - public - void test_canonical() { - byte[] exp = new byte[] {1, 'm', 1, 'h', 1, 'n', 0, // host - 1, 'm', 1, 'a', 1, 'n', 0, // admin - (byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x12, // serial - (byte) 0xCD, (byte) 0xEF, (byte) 0x12, (byte) 0x34, // refresh - (byte) 0xEF, (byte) 0x12, (byte) 0x34, (byte) 0x56, // retry - (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, // expire - (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x9A}; // minimum - - SOARecord ar = new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, m_minimum); - DnsOutput o = new DnsOutput(); - ar.rrToWire(o, null, true); - - assertTrue(Arrays.equals(exp, o.toByteArray())); - } @Override - protected - void setUp() throws TextParseException { - m_an = Name.fromString("My.Abs.Name."); - m_ttl = 0x13A8; - m_host = Name.fromString("M.h.N."); - m_admin = Name.fromString("M.a.n."); - m_serial = 0xABCDEF12L; - m_refresh = 0xCDEF1234L; - m_retry = 0xEF123456L; - m_expire = 0x12345678L; - m_minimum = 0x3456789AL; - } - - public - void test_case_sensitive() { - byte[] exp = new byte[] {1, 'M', 1, 'h', 1, 'N', 0, // host - 1, 'M', 1, 'a', 1, 'n', 0, // admin - (byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x12, // serial - (byte) 0xCD, (byte) 0xEF, (byte) 0x12, (byte) 0x34, // refresh - (byte) 0xEF, (byte) 0x12, (byte) 0x34, (byte) 0x56, // retry - (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, // expire - (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x9A}; // minimum - - SOARecord ar = new SOARecord(m_an, DnsClass.IN, m_ttl, m_host, m_admin, m_serial, m_refresh, m_retry, m_expire, m_minimum); - DnsOutput o = new DnsOutput(); - ar.rrToWire(o, null, false); - - assertTrue(Arrays.equals(exp, o.toByteArray())); - } - - - } - - public static - Test suite() { - TestSuite s = new TestSuite(); - s.addTestSuite(Test_init.class); - s.addTestSuite(Test_rrFromWire.class); - s.addTestSuite(Test_rdataFromString.class); - s.addTestSuite(Test_rrToString.class); - s.addTestSuite(Test_rrToWire.class); - return s; - } -} diff --git a/test/dorkbox/network/dns/records/SectionTest.java b/test/dorkbox/network/dns/records/SectionTest.java deleted file mode 100644 index 0f7e1566..00000000 --- a/test/dorkbox/network/dns/records/SectionTest.java +++ /dev/null @@ -1,100 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.constants.DnsSection; -import junit.framework.TestCase; - -public -class SectionTest extends TestCase { - public - void test_string() { - // a regular one - assertEquals("au", DnsSection.string(DnsSection.AUTHORITY)); - - try { - DnsSection.string(-1); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - - // (max is 3) - try { - DnsSection.string(4); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_value() { - // regular one - assertEquals(DnsSection.ADDITIONAL, DnsSection.value("ad")); - - // something that unknown - assertEquals(-1, DnsSection.value("THIS IS DEFINITELY UNKNOWN")); - - // empty string - assertEquals(-1, DnsSection.value("")); - } - - public - void test_longString() { - assertEquals("ADDITIONAL RECORDS", DnsSection.longString(DnsSection.ADDITIONAL)); - - try { - DnsSection.longString(-1); - } catch (IllegalArgumentException e) { - } - try { - DnsSection.longString(4); - } catch (IllegalArgumentException e) { - } - } - - public - void test_updString() { - assertEquals("ZONE", DnsSection.updString(DnsSection.ZONE)); - - try { - DnsSection.longString(-1); - } catch (IllegalArgumentException e) { - } - try { - DnsSection.longString(4); - } catch (IllegalArgumentException e) { - } - } -} diff --git a/test/dorkbox/network/dns/records/SingleCompressedNameBaseTest.java b/test/dorkbox/network/dns/records/SingleCompressedNameBaseTest.java deleted file mode 100644 index 6e52814d..00000000 --- a/test/dorkbox/network/dns/records/SingleCompressedNameBaseTest.java +++ /dev/null @@ -1,118 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class SingleCompressedNameBaseTest extends TestCase { - private static - class TestClass extends SingleCompressedNameBase { - public - TestClass() {} - - public - TestClass(Name name, int type, int dclass, long ttl, Name singleName, String desc) { - super(name, type, dclass, ttl, singleName, desc); - } - - @Override - public - Name getSingleName() { - return super.getSingleName(); - } - - @Override - public - DnsRecord getObject() { - return null; - } - } - - public - void test_ctor() throws TextParseException { - TestClass tc = new TestClass(); - assertNull(tc.getSingleName()); - - Name n = Name.fromString("my.name."); - Name sn = Name.fromString("my.single.name."); - - tc = new TestClass(n, DnsRecordType.A, DnsClass.IN, 100L, sn, "The Description"); - - assertSame(n, tc.getName()); - assertEquals(DnsRecordType.A, tc.getType()); - assertEquals(DnsClass.IN, tc.getDClass()); - assertEquals(100L, tc.getTTL()); - assertSame(sn, tc.getSingleName()); - } - - public - void test_rrToWire() throws IOException, TextParseException { - Name n = Name.fromString("my.name."); - Name sn = Name.fromString("My.Single.Name."); - - // non-canonical (case sensitive) - TestClass tc = new TestClass(n, DnsRecordType.A, DnsClass.IN, 100L, sn, "The Description"); - byte[] exp = new byte[] {2, 'M', 'y', 6, 'S', 'i', 'n', 'g', 'l', 'e', 4, 'N', 'a', 'm', 'e', 0}; - - DnsOutput dout = new DnsOutput(); - tc.rrToWire(dout, null, false); - - byte[] out = dout.toByteArray(); - assertEquals(exp, out); - - // canonical (lowercase) - tc = new TestClass(n, DnsRecordType.A, DnsClass.IN, 100L, sn, "The Description"); - exp = new byte[] {2, 'm', 'y', 6, 's', 'i', 'n', 'g', 'l', 'e', 4, 'n', 'a', 'm', 'e', 0}; - - dout = new DnsOutput(); - tc.rrToWire(dout, null, true); - - out = dout.toByteArray(); - assertEquals(exp, out); - } - - private - void assertEquals(byte[] exp, byte[] act) { - assertTrue(java.util.Arrays.equals(exp, act)); - } -} diff --git a/test/dorkbox/network/dns/records/SingleNameBaseTest.java b/test/dorkbox/network/dns/records/SingleNameBaseTest.java deleted file mode 100644 index 5e122b00..00000000 --- a/test/dorkbox/network/dns/records/SingleNameBaseTest.java +++ /dev/null @@ -1,178 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.RelativeNameException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.TestCase; - -public -class SingleNameBaseTest extends TestCase { - private static - class TestClass extends SingleNameBase { - public - TestClass() {} - - public - TestClass(Name name, int type, int dclass, long ttl) { - super(name, type, dclass, ttl); - } - - public - TestClass(Name name, int type, int dclass, long ttl, Name singleName, String desc) { - super(name, type, dclass, ttl, singleName, desc); - } - - @Override - public - Name getSingleName() { - return super.getSingleName(); - } - - @Override - public - DnsRecord getObject() { - return null; - } - } - - public - void test_ctor() throws TextParseException { - TestClass tc = new TestClass(); - assertNull(tc.getSingleName()); - - Name n = Name.fromString("my.name."); - Name sn = Name.fromString("my.single.name."); - - tc = new TestClass(n, DnsRecordType.A, DnsClass.IN, 100L); - - assertSame(n, tc.getName()); - assertEquals(DnsRecordType.A, tc.getType()); - assertEquals(DnsClass.IN, tc.getDClass()); - assertEquals(100L, tc.getTTL()); - - tc = new TestClass(n, DnsRecordType.A, DnsClass.IN, 100L, sn, "The Description"); - - assertSame(n, tc.getName()); - assertEquals(DnsRecordType.A, tc.getType()); - assertEquals(DnsClass.IN, tc.getDClass()); - assertEquals(100L, tc.getTTL()); - assertSame(sn, tc.getSingleName()); - } - - public - void test_rrFromWire() throws IOException { - byte[] raw = new byte[] {2, 'm', 'y', 6, 's', 'i', 'n', 'g', 'l', 'e', 4, 'n', 'a', 'm', 'e', 0}; - DnsInput in = new DnsInput(raw); - - TestClass tc = new TestClass(); - tc.rrFromWire(in); - - Name exp = Name.fromString("my.single.name."); - assertEquals(exp, tc.getSingleName()); - } - - public - void test_rdataFromString() throws IOException { - Name exp = Name.fromString("my.single.name."); - - Tokenizer t = new Tokenizer("my.single.name."); - TestClass tc = new TestClass(); - tc.rdataFromString(t, null); - assertEquals(exp, tc.getSingleName()); - - t = new Tokenizer("my.relative.name"); - tc = new TestClass(); - try { - tc.rdataFromString(t, null); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException e) { - } - } - - public - void test_rrToString() throws IOException, TextParseException { - Name exp = Name.fromString("my.single.name."); - - Tokenizer t = new Tokenizer("my.single.name."); - TestClass tc = new TestClass(); - tc.rdataFromString(t, null); - assertEquals(exp, tc.getSingleName()); - - StringBuilder sb = new StringBuilder(); - tc.rrToString(sb); - String out = sb.toString(); - assertEquals(out, exp.toString()); - } - - public - void test_rrToWire() throws IOException, TextParseException { - Name n = Name.fromString("my.name."); - Name sn = Name.fromString("My.Single.Name."); - - // non-canonical (case sensitive) - TestClass tc = new TestClass(n, DnsRecordType.A, DnsClass.IN, 100L, sn, "The Description"); - byte[] exp = new byte[] {2, 'M', 'y', 6, 'S', 'i', 'n', 'g', 'l', 'e', 4, 'N', 'a', 'm', 'e', 0}; - - DnsOutput dout = new DnsOutput(); - tc.rrToWire(dout, null, false); - - byte[] out = dout.toByteArray(); - assertEquals(exp, out); - - // canonical (lowercase) - tc = new TestClass(n, DnsRecordType.A, DnsClass.IN, 100L, sn, "The Description"); - exp = new byte[] {2, 'm', 'y', 6, 's', 'i', 'n', 'g', 'l', 'e', 4, 'n', 'a', 'm', 'e', 0}; - - dout = new DnsOutput(); - tc.rrToWire(dout, null, true); - - out = dout.toByteArray(); - assertEquals(exp, out); - } - - private - void assertEquals(byte[] exp, byte[] act) { - assertTrue(java.util.Arrays.equals(exp, act)); - } -} diff --git a/test/dorkbox/network/dns/records/TSIGTest.java b/test/dorkbox/network/dns/records/TSIGTest.java deleted file mode 100644 index 0158eefd..00000000 --- a/test/dorkbox/network/dns/records/TSIGTest.java +++ /dev/null @@ -1,90 +0,0 @@ -package dorkbox.network.dns.records; - -import java.io.IOException; - -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.constants.DnsResponseCode; -import dorkbox.network.dns.constants.DnsSection; -import dorkbox.network.dns.constants.Flags; -import dorkbox.network.dns.exceptions.TextParseException; -import junit.framework.TestCase; - -public -class TSIGTest extends TestCase { - public - void test_TSIG_query() throws TextParseException, IOException { - TSIG key = new TSIG(TSIG.HMAC_SHA256, "example.", "12345678"); - - Name qname = Name.fromString("www.example."); - DnsRecord rec = DnsRecord.newRecord(qname, DnsRecordType.A, DnsClass.IN); - DnsMessage msg = DnsMessage.newQuery(rec); - msg.setTSIG(key, DnsResponseCode.NOERROR, null); - byte[] bytes = msg.toWire(512); - assertEquals(bytes[11], 1); - - DnsMessage parsed = new DnsMessage(bytes); - int result = key.verify(parsed, bytes, null); - assertEquals(result, DnsResponseCode.NOERROR); - assertTrue(parsed.isSigned()); - } - - public - void test_TSIG_response() throws TextParseException, IOException { - TSIG key = new TSIG(TSIG.HMAC_SHA256, "example.", "12345678"); - - Name qname = Name.fromString("www.example."); - DnsRecord question = DnsRecord.newRecord(qname, DnsRecordType.A, DnsClass.IN); - DnsMessage query = DnsMessage.newQuery(question); - query.setTSIG(key, DnsResponseCode.NOERROR, null); - byte[] qbytes = query.toWire(); - DnsMessage qparsed = new DnsMessage(qbytes); - - DnsMessage response = new DnsMessage(query.getHeader() - .getID()); - response.setTSIG(key, DnsResponseCode.NOERROR, qparsed.getTSIG()); - response.getHeader() - .setFlag(Flags.QR); - response.addRecord(question, DnsSection.QUESTION); - DnsRecord answer = DnsRecord.fromString(qname, DnsRecordType.A, DnsClass.IN, 300, "1.2.3.4", null); - response.addRecord(answer, DnsSection.ANSWER); - byte[] bytes = response.toWire(512); - - DnsMessage parsed = new DnsMessage(bytes); - int result = key.verify(parsed, bytes, qparsed.getTSIG()); - assertEquals(result, DnsResponseCode.NOERROR); - assertTrue(parsed.isSigned()); - } - - public - void test_TSIG_truncated() throws TextParseException, IOException { - TSIG key = new TSIG(TSIG.HMAC_SHA256, "example.", "12345678"); - - Name qname = Name.fromString("www.example."); - DnsRecord question = DnsRecord.newRecord(qname, DnsRecordType.A, DnsClass.IN); - DnsMessage query = DnsMessage.newQuery(question); - query.setTSIG(key, DnsResponseCode.NOERROR, null); - byte[] qbytes = query.toWire(); - DnsMessage qparsed = new DnsMessage(qbytes); - - DnsMessage response = new DnsMessage(query.getHeader() - .getID()); - response.setTSIG(key, DnsResponseCode.NOERROR, qparsed.getTSIG()); - response.getHeader() - .setFlag(Flags.QR); - response.addRecord(question, DnsSection.QUESTION); - for (int i = 0; i < 40; i++) { - DnsRecord answer = DnsRecord.fromString(qname, DnsRecordType.TXT, DnsClass.IN, 300, "foo" + i, null); - response.addRecord(answer, DnsSection.ANSWER); - } - byte[] bytes = response.toWire(512); - - DnsMessage parsed = new DnsMessage(bytes); - assertTrue(parsed.getHeader() - .getFlag(Flags.TC)); - int result = key.verify(parsed, bytes, qparsed.getTSIG()); - assertEquals(result, DnsResponseCode.NOERROR); - assertTrue(parsed.isSigned()); - } -} diff --git a/test/dorkbox/network/dns/records/TTLTest.java b/test/dorkbox/network/dns/records/TTLTest.java deleted file mode 100644 index cc5588d5..00000000 --- a/test/dorkbox/network/dns/records/TTLTest.java +++ /dev/null @@ -1,146 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import dorkbox.network.dns.exceptions.InvalidTTLException; -import junit.framework.TestCase; - -public -class TTLTest extends TestCase { - private final long S = 1; - private final long M = 60 * S; - private final long H = 60 * M; - private final long D = 24 * H; - private final long W = 7 * D; - - public - void test_parseTTL() { - assertEquals(9876, TTL.parseTTL("9876")); - - assertEquals(0, TTL.parseTTL("0S")); - assertEquals(0, TTL.parseTTL("0M")); - assertEquals(0, TTL.parseTTL("0H")); - assertEquals(0, TTL.parseTTL("0D")); - assertEquals(0, TTL.parseTTL("0W")); - - assertEquals(S, TTL.parseTTL("1s")); - assertEquals(M, TTL.parseTTL("1m")); - assertEquals(H, TTL.parseTTL("1h")); - assertEquals(D, TTL.parseTTL("1d")); - assertEquals(W, TTL.parseTTL("1w")); - - assertEquals(98 * S, TTL.parseTTL("98S")); - assertEquals(76 * M, TTL.parseTTL("76M")); - assertEquals(54 * H, TTL.parseTTL("54H")); - assertEquals(32 * D, TTL.parseTTL("32D")); - assertEquals(10 * W, TTL.parseTTL("10W")); - - assertEquals(98 * S + 11 * M + 1234 * H + 2 * D + W, TTL.parseTTL("98S11M1234H2D01W")); - } - - public - void test_parseTTL_invalid() { - try { - TTL.parseTTL(null); - fail("NumberFormatException not throw"); - } catch (NumberFormatException ignored) { - } - - try { - TTL.parseTTL(""); - fail("NumberFormatException not throw"); - } catch (NumberFormatException ignored) { - } - - try { - TTL.parseTTL("S"); - fail("NumberFormatException not throw"); - } catch (NumberFormatException ignored) { - } - - try { - TTL.parseTTL("10S4B"); - fail("NumberFormatException not throw"); - } catch (NumberFormatException ignored) { - } - - try { - TTL.parseTTL("1S" + 0xFFFFFFFFL + "S"); - fail("NumberFormatException not throw"); - } catch (NumberFormatException ignored) { - } - - try { - TTL.parseTTL("" + 0x100000000L); - fail("NumberFormatException not throw"); - } catch (NumberFormatException ignored) { - } - } - - public - void test_format() { - assertEquals("0S", TTL.format(0)); - assertEquals("1S", TTL.format(1)); - assertEquals("59S", TTL.format(59)); - assertEquals("1M", TTL.format(60)); - assertEquals("59M", TTL.format(59 * M)); - assertEquals("1M33S", TTL.format(M + 33)); - assertEquals("59M59S", TTL.format(59 * M + 59 * S)); - assertEquals("1H", TTL.format(H)); - assertEquals("10H1M21S", TTL.format(10 * H + M + 21)); - assertEquals("23H59M59S", TTL.format(23 * H + 59 * M + 59)); - assertEquals("1D", TTL.format(D)); - assertEquals("4D18H45M30S", TTL.format(4 * D + 18 * H + 45 * M + 30)); - assertEquals("6D23H59M59S", TTL.format(6 * D + 23 * H + 59 * M + 59)); - assertEquals("1W", TTL.format(W)); - assertEquals("10W4D1H21M29S", TTL.format(10 * W + 4 * D + H + 21 * M + 29)); - assertEquals("3550W5D3H14M7S", TTL.format(0x7FFFFFFFL)); - } - - public - void test_format_invalid() { - try { - TTL.format(-1); - fail("InvalidTTLException not thrown"); - } catch (InvalidTTLException ignored) { - } - - try { - TTL.format(0x100000000L); - fail("InvalidTTLException not thrown"); - } catch (InvalidTTLException ignored) { - } - } -} diff --git a/test/dorkbox/network/dns/records/TypeBitmapTest.java b/test/dorkbox/network/dns/records/TypeBitmapTest.java deleted file mode 100644 index f12b505d..00000000 --- a/test/dorkbox/network/dns/records/TypeBitmapTest.java +++ /dev/null @@ -1,57 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2011, org.xbill.DNS -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import junit.framework.TestCase; - -public -class TypeBitmapTest extends TestCase { - public - void test_empty() { - TypeBitmap typeBitmap = new TypeBitmap(new int[] {}); - assertEquals(typeBitmap.toString(), ""); - } - - public - void test_typeA() { - TypeBitmap typeBitmap = new TypeBitmap(new int[] {1}); - assertEquals(typeBitmap.toString(), "A"); - } - - public - void test_typeNSandSOA() { - TypeBitmap typeBitmap = new TypeBitmap(new int[] {2, 6}); - assertEquals(typeBitmap.toString(), "NS SOA"); - } -} diff --git a/test/dorkbox/network/dns/records/U16NameBaseTest.java b/test/dorkbox/network/dns/records/U16NameBaseTest.java deleted file mode 100644 index 50652a27..00000000 --- a/test/dorkbox/network/dns/records/U16NameBaseTest.java +++ /dev/null @@ -1,216 +0,0 @@ -// -*- Java -*- -// -// Copyright (c) 2005, Matthew J. Rutherford -// Copyright (c) 2005, University of Colorado at Boulder -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// * Neither the name of the University of Colorado at Boulder nor the -// names of its contributors may be used to endorse or promote -// products derived from this software without specific prior written -// permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.util.Arrays; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.RelativeNameException; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.TestCase; - -public -class U16NameBaseTest extends TestCase { - private - void assertEquals(byte[] exp, byte[] act) { - assertTrue(java.util.Arrays.equals(exp, act)); - } - - private static - class TestClass extends U16NameBase { - public - TestClass() {} - - public - TestClass(Name name, int type, int dclass, long ttl) { - super(name, type, dclass, ttl); - } - - public - TestClass(Name name, int type, int dclass, long ttl, int u16Field, String u16Description, Name nameField, String nameDescription) { - super(name, type, dclass, ttl, u16Field, u16Description, nameField, nameDescription); - } - - @Override - public - int getU16Field() { - return super.getU16Field(); - } - - @Override - public - Name getNameField() { - return super.getNameField(); - } - - @Override - public - DnsRecord getObject() { - return null; - } - } - - public - void test_ctor_0arg() { - TestClass tc = new TestClass(); - assertNull(tc.getName()); - assertEquals(0, tc.getType()); - assertEquals(0, tc.getDClass()); - assertEquals(0, tc.getTTL()); - assertEquals(0, tc.getU16Field()); - assertNull(tc.getNameField()); - } - - public - void test_ctor_4arg() throws TextParseException { - Name n = Name.fromString("My.Name."); - - TestClass tc = new TestClass(n, DnsRecordType.MX, DnsClass.IN, 0xBCDA); - - assertSame(n, tc.getName()); - assertEquals(DnsRecordType.MX, tc.getType()); - assertEquals(DnsClass.IN, tc.getDClass()); - assertEquals(0xBCDA, tc.getTTL()); - assertEquals(0, tc.getU16Field()); - assertNull(tc.getNameField()); - } - - public - void test_ctor_8arg() throws TextParseException { - Name n = Name.fromString("My.Name."); - Name m = Name.fromString("My.Other.Name."); - - TestClass tc = new TestClass(n, DnsRecordType.MX, DnsClass.IN, 0xB12FL, 0x1F2B, "u16 description", m, "name description"); - - assertSame(n, tc.getName()); - assertEquals(DnsRecordType.MX, tc.getType()); - assertEquals(DnsClass.IN, tc.getDClass()); - assertEquals(0xB12FL, tc.getTTL()); - assertEquals(0x1F2B, tc.getU16Field()); - assertEquals(m, tc.getNameField()); - - // an invalid u16 value - try { - new TestClass(n, DnsRecordType.MX, DnsClass.IN, 0xB12FL, 0x10000, "u16 description", m, "name description"); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - - // a relative name - Name rel = Name.fromString("My.relative.Name"); - try { - new TestClass(n, DnsRecordType.MX, DnsClass.IN, 0xB12FL, 0x1F2B, "u16 description", rel, "name description"); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException e) { - } - - } - - public - void test_rrFromWire() throws IOException { - byte[] raw = new byte[] {(byte) 0xBC, (byte) 0x1F, 2, 'M', 'y', 6, 's', 'i', 'N', 'g', 'l', 'E', 4, 'n', 'A', 'm', 'E', 0}; - DnsInput in = new DnsInput(raw); - - TestClass tc = new TestClass(); - tc.rrFromWire(in); - - Name exp = Name.fromString("My.single.name."); - assertEquals(0xBC1FL, tc.getU16Field()); - assertEquals(exp, tc.getNameField()); - } - - public - void test_rdataFromString() throws IOException { - Name exp = Name.fromString("My.Single.Name."); - - Tokenizer t = new Tokenizer(0x19A2 + " My.Single.Name."); - TestClass tc = new TestClass(); - tc.rdataFromString(t, null); - - assertEquals(0x19A2, tc.getU16Field()); - assertEquals(exp, tc.getNameField()); - - t = new Tokenizer("10 My.Relative.Name"); - tc = new TestClass(); - try { - tc.rdataFromString(t, null); - fail("RelativeNameException not thrown"); - } catch (RelativeNameException e) { - } - } - - public - void test_rrToString() throws IOException, TextParseException { - Name n = Name.fromString("My.Name."); - Name m = Name.fromString("My.Other.Name."); - - TestClass tc = new TestClass(n, DnsRecordType.MX, DnsClass.IN, 0xB12FL, 0x1F2B, "u16 description", m, "name description"); - - StringBuilder sb = new StringBuilder(); - tc.rrToString(sb); - String out = sb.toString(); - String exp = 0x1F2B + " My.Other.Name."; - - assertEquals(exp, out); - } - - public - void test_rrToWire() throws IOException, TextParseException { - Name n = Name.fromString("My.Name."); - Name m = Name.fromString("M.O.n."); - - TestClass tc = new TestClass(n, DnsRecordType.MX, DnsClass.IN, 0xB12FL, 0x1F2B, "u16 description", m, "name description"); - - // canonical - DnsOutput dout = new DnsOutput(); - tc.rrToWire(dout, null, true); - byte[] out = dout.toByteArray(); - byte[] exp = new byte[] {0x1F, 0x2B, 1, 'm', 1, 'o', 1, 'n', 0}; - assertTrue(Arrays.equals(exp, out)); - - // case sensitive - dout = new DnsOutput(); - tc.rrToWire(dout, null, false); - out = dout.toByteArray(); - exp = new byte[] {0x1F, 0x2B, 1, 'M', 1, 'O', 1, 'n', 0}; - assertTrue(Arrays.equals(exp, out)); - } -} diff --git a/test/dorkbox/network/dns/records/URIRecordTest.java b/test/dorkbox/network/dns/records/URIRecordTest.java deleted file mode 100644 index 50bd2c01..00000000 --- a/test/dorkbox/network/dns/records/URIRecordTest.java +++ /dev/null @@ -1,125 +0,0 @@ -package dorkbox.network.dns.records; - -import java.io.IOException; -import java.util.Arrays; - -import dorkbox.network.dns.DnsInput; -import dorkbox.network.dns.DnsOutput; -import dorkbox.network.dns.Name; -import dorkbox.network.dns.constants.DnsClass; -import dorkbox.network.dns.constants.DnsRecordType; -import dorkbox.network.dns.exceptions.TextParseException; -import dorkbox.network.dns.utils.Tokenizer; -import junit.framework.TestCase; - -public -class URIRecordTest extends TestCase { - public - void test_ctor_0arg() { - URIRecord r = new URIRecord(); - assertNull(r.getName()); - assertEquals(0, r.getType()); - assertEquals(0, r.getDClass()); - assertEquals(0, r.getTTL()); - assertEquals(0, r.getPriority()); - assertEquals(0, r.getWeight()); - assertTrue("".equals(r.getTarget())); - } - - public - void test_getObject() { - URIRecord dr = new URIRecord(); - DnsRecord r = dr.getObject(); - assertTrue(r instanceof URIRecord); - } - - public - void test_ctor_6arg() throws TextParseException { - Name n = Name.fromString("my.name."); - String target = ("http://foo"); - - URIRecord r = new URIRecord(n, DnsClass.IN, 0xABCDEL, 42, 69, target); - assertEquals(n, r.getName()); - assertEquals(DnsRecordType.URI, r.getType()); - assertEquals(DnsClass.IN, r.getDClass()); - assertEquals(0xABCDEL, r.getTTL()); - assertEquals(42, r.getPriority()); - assertEquals(69, r.getWeight()); - assertEquals(target, r.getTarget()); - } - - public - void test_rdataFromString() throws IOException { - Tokenizer t = new Tokenizer(0xABCD + " " + 0xEF01 + " " + "\"http://foo:1234/bar?baz=bum\""); - - URIRecord r = new URIRecord(); - r.rdataFromString(t, null); - assertEquals(0xABCD, r.getPriority()); - assertEquals(0xEF01, r.getWeight()); - assertEquals("http://foo:1234/bar?baz=bum", r.getTarget()); - } - - public - void test_rdataToWire() throws TextParseException { - Name n = Name.fromString("my.name."); - String target = ("http://foo"); - byte[] exp = new byte[] {(byte) 0xbe, (byte) 0xef, (byte) 0xde, (byte) 0xad, (byte) 0x68, (byte) 0x74, (byte) 0x74, (byte) 0x70, - (byte) 0x3a, (byte) 0x2f, (byte) 0x2f, (byte) 0x66, (byte) 0x6f, (byte) 0x6f}; - - URIRecord r = new URIRecord(n, DnsClass.IN, 0xABCDEL, 0xbeef, 0xdead, target); - DnsOutput out = new DnsOutput(); - r.rrToWire(out, null, true); - assertTrue(Arrays.equals(exp, out.toByteArray())); - } - - public - void test_rrFromWire() throws IOException { - byte[] raw = new byte[] {(byte) 0xbe, (byte) 0xef, (byte) 0xde, (byte) 0xad, (byte) 0x68, (byte) 0x74, (byte) 0x74, (byte) 0x70, - (byte) 0x3a, (byte) 0x2f, (byte) 0x2f, (byte) 0x66, (byte) 0x6f, (byte) 0x6f}; - DnsInput in = new DnsInput(raw); - - URIRecord r = new URIRecord(); - r.rrFromWire(in); - assertEquals(0xBEEF, r.getPriority()); - assertEquals(0xDEAD, r.getWeight()); - assertEquals("http://foo", r.getTarget()); - } - - public - void test_toobig_priority() throws TextParseException { - try { - new URIRecord(Name.fromString("the.name"), DnsClass.IN, 0x1234, 0x10000, 42, "http://foo"); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_toosmall_priority() throws TextParseException { - try { - new URIRecord(Name.fromString("the.name"), DnsClass.IN, 0x1234, -1, 42, "http://foo"); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_toobig_weight() throws TextParseException { - try { - new URIRecord(Name.fromString("the.name"), DnsClass.IN, 0x1234, 42, 0x10000, "http://foo"); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - - public - void test_toosmall_weight() throws TextParseException { - try { - new URIRecord(Name.fromString("the.name"), DnsClass.IN, 0x1234, 42, -1, "http://foo"); - fail("IllegalArgumentException not thrown"); - } catch (IllegalArgumentException e) { - } - } - -} -