├── .github └── workflows │ └── ci.yml ├── .gitignore ├── LICENCE ├── LICENCE_APACHE ├── LICENCE_LGPL2.1 ├── LICENCE_WTFPL ├── Makefile ├── README.md ├── build-logic ├── build.gradle ├── settings.gradle └── src │ └── main │ └── groovy │ ├── org.minidns.android-boot-classpath-conventions.gradle │ ├── org.minidns.android-conventions.gradle │ ├── org.minidns.application-conventions.gradle │ ├── org.minidns.common-conventions.gradle │ ├── org.minidns.java-conventions.gradle │ └── org.minidns.javadoc-conventions.gradle ├── build.gradle ├── config ├── checkstyle │ ├── checkstyle.xml │ ├── header.txt │ └── suppressions.xml └── scalaStyle.xml ├── gradle.properties.example ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── minidns-android23 ├── build.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── minidns │ │ └── dnsserverlookup │ │ └── android21 │ │ └── AndroidUsingLinkProperties.java │ └── test │ └── java │ └── org │ └── minidns │ └── dnsserverlookup │ └── android21 │ └── AndroidUsingLinkPropertiesTest.java ├── minidns-async ├── build.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── minidns │ │ └── source │ │ └── async │ │ ├── AsyncDnsRequest.java │ │ ├── AsyncNetworkDataSource.java │ │ └── ChannelSelectedHandler.java │ └── test │ └── java │ └── org │ └── minidns │ └── source │ └── async │ └── AsyncNetworkDataSourceTest.java ├── minidns-client ├── build.gradle └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── minidns │ │ │ ├── AbstractDnsClient.java │ │ │ ├── DnsCache.java │ │ │ ├── DnsClient.java │ │ │ ├── MiniDnsConfiguration.java │ │ │ ├── MiniDnsException.java │ │ │ ├── MiniDnsFuture.java │ │ │ ├── MiniDnsInitialization.java │ │ │ ├── RrSet.java │ │ │ ├── cache │ │ │ ├── ExtendedLruCache.java │ │ │ ├── FullLruCache.java │ │ │ ├── LruCache.java │ │ │ └── MiniDnsCacheFactory.java │ │ │ ├── dnsqueryresult │ │ │ ├── CachedDnsQueryResult.java │ │ │ ├── DirectCachedDnsQueryResult.java │ │ │ ├── DnsQueryResult.java │ │ │ ├── StandardDnsQueryResult.java │ │ │ └── SynthesizedCachedDnsQueryResult.java │ │ │ ├── dnsserverlookup │ │ │ ├── AbstractDnsServerLookupMechanism.java │ │ │ ├── AndroidUsingExec.java │ │ │ ├── AndroidUsingReflection.java │ │ │ ├── DnsServerLookupMechanism.java │ │ │ └── UnixUsingEtcResolvConf.java │ │ │ └── source │ │ │ ├── AbstractDnsDataSource.java │ │ │ ├── DnsDataSource.java │ │ │ ├── NetworkDataSource.java │ │ │ └── NetworkDataSourceWithAccounting.java │ └── resources │ │ └── de.measite.minidns │ │ └── .keep │ └── test │ └── java │ └── org │ └── minidns │ ├── DnsClientTest.java │ ├── DnsWorld.java │ ├── LruCacheTest.java │ ├── dnsqueryresult │ └── TestWorldDnsQueryResult.java │ ├── dnsserverlookup │ └── AndroidUsingExecTest.java │ └── source │ └── NetworkDataSourceTest.java ├── minidns-core ├── build.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── minidns │ │ ├── constants │ │ ├── DnsRootServer.java │ │ └── DnssecConstants.java │ │ ├── dnslabel │ │ ├── ALabel.java │ │ ├── DnsLabel.java │ │ ├── FakeALabel.java │ │ ├── LdhLabel.java │ │ ├── LeadingOrTrailingHyphenLabel.java │ │ ├── NonLdhLabel.java │ │ ├── NonReservedLdhLabel.java │ │ ├── OtherNonLdhLabel.java │ │ ├── ReservedLdhLabel.java │ │ ├── UnderscoreLabel.java │ │ └── XnLabel.java │ │ ├── dnsmessage │ │ ├── DnsMessage.java │ │ └── Question.java │ │ ├── dnsname │ │ ├── DnsName.java │ │ └── InvalidDnsNameException.java │ │ ├── edns │ │ ├── Edns.java │ │ ├── EdnsOption.java │ │ ├── Nsid.java │ │ └── UnknownEdnsOption.java │ │ ├── idna │ │ ├── DefaultIdnaTransformator.java │ │ ├── IdnaTransformator.java │ │ └── MiniDnsIdna.java │ │ ├── record │ │ ├── A.java │ │ ├── AAAA.java │ │ ├── CNAME.java │ │ ├── DLV.java │ │ ├── DNAME.java │ │ ├── DNSKEY.java │ │ ├── DS.java │ │ ├── Data.java │ │ ├── DelegatingDnssecRR.java │ │ ├── InternetAddressRR.java │ │ ├── MX.java │ │ ├── NS.java │ │ ├── NSEC.java │ │ ├── NSEC3.java │ │ ├── NSEC3PARAM.java │ │ ├── OPENPGPKEY.java │ │ ├── OPT.java │ │ ├── PTR.java │ │ ├── RRSIG.java │ │ ├── RRWithTarget.java │ │ ├── Record.java │ │ ├── SOA.java │ │ ├── SRV.java │ │ ├── TLSA.java │ │ ├── TXT.java │ │ └── UNKNOWN.java │ │ └── util │ │ ├── Base32.java │ │ ├── Base64.java │ │ ├── CallbackRecipient.java │ │ ├── CollectionsUtil.java │ │ ├── ExceptionCallback.java │ │ ├── Hex.java │ │ ├── InetAddressUtil.java │ │ ├── MultipleIoException.java │ │ ├── NameUtil.java │ │ ├── PlatformDetection.java │ │ ├── SafeCharSequence.java │ │ ├── SrvUtil.java │ │ └── SuccessCallback.java │ └── test │ ├── java │ └── org │ │ └── minidns │ │ ├── Assert.java │ │ ├── dnslabel │ │ └── DnsLabelTest.java │ │ ├── dnsmessage │ │ └── DnsMessageTest.java │ │ ├── dnsname │ │ └── DnsNameTest.java │ │ ├── record │ │ ├── RecordsTest.java │ │ └── TLSATest.java │ │ └── util │ │ ├── Base32Test.java │ │ ├── Base64Test.java │ │ ├── InetAddressUtilTest.java │ │ ├── NameUtilTest.java │ │ └── SrvUtilTest.java │ └── resources │ └── org │ └── minidns │ └── dnsmessage │ ├── codinghorror-txt │ ├── com-ds-rrsig │ ├── com-ns │ ├── com-nsec3 │ ├── example-nsec │ ├── gmail-domainkey-txt │ ├── gmail-mx │ ├── google-aaaa │ ├── gpn-srv │ ├── oracle-soa │ ├── root-dnskey │ └── sun-a ├── minidns-dane ├── build.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── minidns │ │ └── dane │ │ └── java7 │ │ └── DaneExtendedTrustManager.java │ └── test │ └── java │ └── org │ └── minidns │ └── dane │ └── java7 │ └── DaneJava7Test.java ├── minidns-dnssec ├── build.gradle └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── minidns │ │ │ ├── dane │ │ │ ├── DaneCertificateException.java │ │ │ ├── DaneVerifier.java │ │ │ ├── ExpectingTrustManager.java │ │ │ └── X509TrustManagerUtil.java │ │ │ └── dnssec │ │ │ ├── DigestCalculator.java │ │ │ ├── DnssecClient.java │ │ │ ├── DnssecQueryResult.java │ │ │ ├── DnssecResultNotAuthenticException.java │ │ │ ├── DnssecUnverifiedReason.java │ │ │ ├── DnssecValidationFailedException.java │ │ │ ├── DnssecValidatorInitializationException.java │ │ │ ├── SignatureVerifier.java │ │ │ ├── Verifier.java │ │ │ └── algorithms │ │ │ ├── AlgorithmMap.java │ │ │ ├── DsaSignatureVerifier.java │ │ │ ├── EcdsaSignatureVerifier.java │ │ │ ├── EcgostSignatureVerifier.java │ │ │ ├── JavaSecDigestCalculator.java │ │ │ ├── JavaSecSignatureVerifier.java │ │ │ └── RsaSignatureVerifier.java │ └── resources │ │ └── .keep-minidns-dnssec-main-resources │ └── test │ ├── java │ └── org │ │ └── minidns │ │ └── dnssec │ │ ├── DnssecClientTest.java │ │ ├── DnssecWorld.java │ │ ├── VerifierTest.java │ │ └── algorithms │ │ ├── AlgorithmTest.java │ │ ├── DigestTest.java │ │ ├── DsaSingatureVerifierTest.java │ │ ├── RsaSignatureVerifierTest.java │ │ └── SignatureVerifierTest.java │ └── resources │ └── .keep-minidns-dnssec-test-resources ├── minidns-hla ├── build.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── minidns │ │ └── hla │ │ ├── DnssecResolverApi.java │ │ ├── ResolutionUnsuccessfulException.java │ │ ├── ResolverApi.java │ │ ├── ResolverResult.java │ │ ├── SrvResolverResult.java │ │ └── srv │ │ ├── SrvProto.java │ │ ├── SrvService.java │ │ ├── SrvServiceProto.java │ │ └── SrvType.java │ └── test │ └── java │ └── org │ └── minidns │ └── hla │ └── MiniDnsHlaTest.java ├── minidns-integration-test ├── build.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── minidns │ │ ├── integrationtest │ │ ├── AsyncApiTest.java │ │ ├── CoreTest.java │ │ ├── DaneTest.java │ │ ├── DnssecTest.java │ │ ├── HlaTest.java │ │ ├── IntegrationTest.java │ │ ├── IntegrationTestHelper.java │ │ ├── IntegrationTestTools.java │ │ ├── IterativeDnssecTest.java │ │ └── NsidTest.java │ │ └── jul │ │ └── MiniDnsJul.java │ └── test │ └── java │ └── org │ └── minidns │ └── integrationtest │ └── IntegrationTestTest.java ├── minidns-iterative-resolver ├── build.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── minidns │ │ └── iterative │ │ ├── IterativeClientException.java │ │ ├── IterativeDnsClient.java │ │ ├── ReliableDnsClient.java │ │ └── ResolutionState.java │ └── test │ └── java │ └── org │ └── minidns │ └── iterative │ └── IterativeDnsClientTest.java ├── minidns-repl ├── build.gradle ├── scala.repl └── src │ ├── main │ └── java │ │ └── org │ │ └── minidns │ │ └── minidnsrepl │ │ ├── DnssecStats.java │ │ ├── MiniDnsRepl.java │ │ └── MiniDnsStats.java │ └── test │ └── java │ └── org │ └── minidns │ └── minidnsrepl │ └── ReplTest.java ├── misc ├── resolve.pl └── sbt │ ├── .gitignore │ └── build.sbt ├── repl ├── settings.gradle └── version /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | name: Build MiniDNS 8 | 9 | runs-on: ubuntu-24.04 10 | strategy: 11 | matrix: 12 | java: 13 | - 17 14 | - 21 15 | env: 16 | PRIMARY_JAVA_VERSION: 21 17 | 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v2 21 | - name: Set up JDK ${{ matrix.java }} 22 | uses: actions/setup-java@v1 23 | with: 24 | java-version: ${{ matrix.java }} 25 | 26 | # Caches 27 | - name: Cache Maven 28 | uses: actions/cache@v2 29 | with: 30 | path: ~/.m2/repository 31 | key: maven-${{ hashFiles('**/build.gradle') }} 32 | restore-keys: | 33 | maven- 34 | - name: Cache Gradle 35 | uses: actions/cache@v2 36 | with: 37 | path: ~/.gradle/caches 38 | key: gradle-caches-${{ hashFiles('**/build.gradle') }} 39 | restore-keys: 40 | gradle-caches 41 | - name: Cache Gradle Binary 42 | uses: actions/cache@v2 43 | with: 44 | path: | 45 | ~/gradle-bin-${GRADLE_VERSION}/ 46 | key: gradle-bin-${GRADLE_VERSION} 47 | - name: Cache Android SDK 48 | uses: actions/cache@v2 49 | with: 50 | path: | 51 | ~/.android/sdk 52 | key: android-${{ hashFiles('build.gradle') }} 53 | restore-keys: | 54 | android- 55 | 56 | # Pre-reqs 57 | - name: Install Android SDK Manager 58 | uses: android-actions/setup-android@v2 59 | - name: Install Android SDK 60 | run: | 61 | sdkmanager \ 62 | "platforms;android-19" \ 63 | "platforms;android-23" 64 | 65 | # Testing 66 | - name: Gradle Check 67 | run: ./gradlew check --stacktrace 68 | 69 | # Test local publish 70 | - name: Gradle publish 71 | run: ./gradlew publishToMavenLocal --stacktrace 72 | 73 | # Javadoc 74 | - name: Javadoc 75 | if: ${{ matrix.java == env.PRIMARY_JAVA_VERSION }} 76 | run: ./gradlew javadocAll --stacktrace 77 | 78 | # Test Coverage Report 79 | - name: Jacoco Test Coverage 80 | run: ./gradlew minidns-hla:testCodeCoverageReport 81 | 82 | # Coveralls 83 | - name: Report coverage stats to Coveralls 84 | if: ${{ matrix.java == env.PRIMARY_JAVA_VERSION }} 85 | uses: coverallsapp/github-action@v2 86 | with: 87 | format: jacoco 88 | file: minidns-hla/build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml 89 | 90 | # Upload build artifacts 91 | - name: Upload build artifacts 92 | uses: actions/upload-artifact@v4 93 | with: 94 | name: smack-java-${{ matrix.java }} 95 | path: | 96 | minidns-*/build/libs/*.jar 97 | !**/*-test-fixtures.jar 98 | !**/*-tests.jar 99 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # From https://github.com/github/gitignore 2 | 3 | # # # # # # # # # # # # 4 | # Android gitignore # 5 | # # # # # # # # # # # # 6 | 7 | # Built application files 8 | *.apk 9 | *.ap_ 10 | 11 | # Files for the Dalvik VM 12 | *.dex 13 | 14 | # Java class files 15 | *.class 16 | 17 | # Generated files 18 | bin/ 19 | gen/ 20 | 21 | # Gradle files 22 | .gradle/ 23 | build/ 24 | 25 | # Local configuration file (sdk path, etc) 26 | local.properties 27 | gradle.properties 28 | 29 | # Proguard folder generated by Eclipse 30 | proguard/ 31 | 32 | # # # # # # # # 33 | # VIM / Linux # 34 | # # # # # # # # 35 | 36 | [._]*.s[a-w][a-z] 37 | [._]s[a-w][a-z] 38 | *.un~ 39 | Session.vim 40 | .netrwhist 41 | *~ 42 | .directory 43 | 44 | # # # # # # 45 | # Eclipse # 46 | # # # # # # 47 | 48 | *.pydevproject 49 | .metadata 50 | .gradle 51 | bin/ 52 | tmp/ 53 | *.tmp 54 | *.bak 55 | *.swp 56 | *~.nib 57 | local.properties 58 | .settings/ 59 | .loadpath 60 | .classpath 61 | .project 62 | 63 | # External tool builders 64 | .externalToolBuilders/ 65 | 66 | # Locally stored "Eclipse launch configurations" 67 | *.launch 68 | 69 | # CDT-specific 70 | .cproject 71 | 72 | # PDT-specific 73 | .buildpath 74 | 75 | # sbteclipse plugin 76 | .target 77 | 78 | # TeXlipse plugin 79 | .texlipse 80 | 81 | # # # # # # # # # 82 | # IntelliJ IDEA # 83 | # # # # # # # # # 84 | 85 | .idea/ 86 | *.iml 87 | 88 | # # # # # 89 | # OS X # 90 | # # # # # 91 | 92 | .DS_Store 93 | .AppleDouble 94 | .LSOverride 95 | 96 | # Icon must ends with two \r. 97 | Icon 98 | 99 | 100 | # Thumbnails 101 | ._* 102 | 103 | # Files that might appear on external disk 104 | .Spotlight-V100 105 | .Trashes 106 | 107 | # Directories potentially created on remote AFP share 108 | .AppleDB 109 | .AppleDesktop 110 | Network Trash Folder 111 | Temporary Items 112 | .apdisk 113 | 114 | # Auto generated version file 115 | /minidns-core/src/main/resources/org.minidns/version 116 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | This software may be used under the terms of (at your choice) 2 | - LGPL version 2 (or later) (see LICENCE_LGPL2.1 for details) 3 | - Apache Software licence (see LICENCE_APACHE for details) 4 | - WTFPL (see LICENCE_WTFPL for details) 5 | -------------------------------------------------------------------------------- /LICENCE_WTFPL: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2014 Rene Treffer 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | GRADLE ?= ./gradlew 2 | 3 | .PHONY: all 4 | all: check codecov eclipse javadocAll inttest 5 | 6 | .PHONY: codecov 7 | codecov: 8 | $(GRADLE) minidns-hla:testCodeCoverageReport 9 | echo "Code coverage report available at $(PWD)/minidns-hla/build/reports/jacoco/testCodeCoverageReport/html/index.html" 10 | 11 | .PHONY: check 12 | check: 13 | $(GRADLE) $@ 14 | 15 | .PHONY: eclipse 16 | eclipse: 17 | $(GRADLE) $@ 18 | 19 | .PHONY: inttest 20 | inttest: 21 | $(GRADLE) $@ 22 | 23 | .PHONY: javadocAll 24 | javadocAll: 25 | $(GRADLE) $@ 26 | echo "javadoc available at $(PWD)/build/javadoc/index.html" 27 | -------------------------------------------------------------------------------- /build-logic/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'groovy-gradle-plugin' 3 | } 4 | 5 | repositories { 6 | gradlePluginPortal() 7 | } 8 | 9 | dependencies { 10 | implementation "biz.aQute.bnd:biz.aQute.bnd.gradle:7.0.0" 11 | implementation "net.ltgt.gradle:gradle-errorprone-plugin:4.0.1" 12 | implementation "ru.vyarus:gradle-animalsniffer-plugin:1.7.1" 13 | } 14 | -------------------------------------------------------------------------------- /build-logic/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'minidns-build-logic' 2 | -------------------------------------------------------------------------------- /build-logic/src/main/groovy/org.minidns.android-boot-classpath-conventions.gradle: -------------------------------------------------------------------------------- 1 | compileJava { 2 | options.bootstrapClasspath = files(androidBootClasspath) 3 | } 4 | javadoc { 5 | classpath += files(androidBootClasspath) 6 | } 7 | -------------------------------------------------------------------------------- /build-logic/src/main/groovy/org.minidns.android-conventions.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'ru.vyarus.animalsniffer' 3 | id 'org.minidns.common-conventions' 4 | } 5 | dependencies { 6 | signature "net.sf.androidscents.signature:android-api-level-${minAndroidSdk}:4.4.2_r4@signature" 7 | } 8 | animalsniffer { 9 | sourceSets = [sourceSets.main] 10 | } 11 | -------------------------------------------------------------------------------- /build-logic/src/main/groovy/org.minidns.application-conventions.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'application' 3 | } 4 | 5 | application { 6 | applicationDefaultJvmArgs = ["-enableassertions"] 7 | } 8 | 9 | run { 10 | // Pass all system properties down to the "application" run 11 | systemProperties System.getProperties() 12 | } 13 | -------------------------------------------------------------------------------- /build-logic/src/main/groovy/org.minidns.common-conventions.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | javaVersion = JavaVersion.VERSION_11 3 | javaMajor = javaVersion.getMajorVersion() 4 | minAndroidSdk = 19 5 | 6 | androidBootClasspath = getAndroidRuntimeJar(minAndroidSdk) 7 | 8 | // Export the function by turning it into a closure. 9 | // https://stackoverflow.com/a/23290820/194894 10 | getAndroidRuntimeJar = this.&getAndroidRuntimeJar 11 | } 12 | 13 | repositories { 14 | mavenLocal() 15 | mavenCentral() 16 | } 17 | 18 | def getAndroidRuntimeJar(androidApiLevel) { 19 | def androidHome = getAndroidHome() 20 | def androidJar = new File("$androidHome/platforms/android-${androidApiLevel}/android.jar") 21 | if (androidJar.isFile()) { 22 | return androidJar 23 | } else { 24 | throw new Exception("Can't find android.jar for API level ${androidApiLevel}. Please install corresponding SDK platform package") 25 | } 26 | } 27 | 28 | def getAndroidHome() { 29 | def androidHomeEnv = System.getenv("ANDROID_HOME") 30 | if (androidHomeEnv == null) { 31 | throw new Exception("ANDROID_HOME environment variable is not set") 32 | } 33 | def androidHome = new File(androidHomeEnv) 34 | if (!androidHome.isDirectory()) throw new Exception("Environment variable ANDROID_HOME is not pointing to a directory") 35 | return androidHome 36 | } 37 | -------------------------------------------------------------------------------- /build-logic/src/main/groovy/org.minidns.javadoc-conventions.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | // Javadoc linking requires repositories to bet configured. And 3 | // those are declared in common-conventions, hence we add it here. 4 | id 'org.minidns.common-conventions' 5 | } 6 | 7 | 8 | tasks.withType(Javadoc) { 9 | // The '-quiet' as second argument is actually a hack, 10 | // since the one parameter addStringOption doesn't seem to 11 | // work, we extra add '-quiet', which is added anyway by 12 | // gradle. 13 | // We disable 'missing' as we do most of javadoc checking via checkstyle. 14 | options.addStringOption('Xdoclint:all,-missing', '-quiet') 15 | // Abort on javadoc warnings. 16 | // See JDK-8200363 (https://bugs.openjdk.java.net/browse/JDK-8200363) 17 | // for information about the -Xwerror option. 18 | options.addStringOption('Xwerror', '-quiet') 19 | options.addStringOption('-release', javaMajor) 20 | } 21 | 22 | tasks.withType(Javadoc) { 23 | options.charSet = "UTF-8" 24 | } 25 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | // The scalastyle plugin of smack-repl wants the root project to 3 | // have a ideaProject task, so let's add one. 4 | id 'idea' 5 | 6 | id 'org.minidns.javadoc-conventions' 7 | } 8 | 9 | ext { 10 | javadocAllDir = new File(buildDir, 'javadoc') 11 | nonJavadocAllProjects = [ 12 | ':minidns-integration-test', 13 | ':minidns-repl', 14 | ].collect{ project(it) } 15 | javadocAllProjects = subprojects - nonJavadocAllProjects 16 | } 17 | 18 | evaluationDependsOnChildren() 19 | task javadocAll(type: Javadoc) { 20 | source javadocAllProjects.collect {project -> 21 | project.sourceSets.main.allJava.findAll { 22 | // Filter out symbolic links to avoid 23 | // "warning: a package-info.java file has already been seen for package" 24 | // javadoc warnings. 25 | !java.nio.file.Files.isSymbolicLink(it.toPath()) 26 | } 27 | } 28 | destinationDir = javadocAllDir 29 | // Might need a classpath 30 | classpath = files(subprojects.collect {project -> 31 | project.sourceSets.main.compileClasspath}) 32 | classpath += files(androidBootClasspath) 33 | options { 34 | linkSource = true 35 | use = true 36 | links = [ 37 | "https://docs.oracle.com/en/java/javase/${javaMajor}/docs/api/", 38 | ] as String[] 39 | overview = "$projectDir/resources/javadoc-overview.html" 40 | } 41 | 42 | // Finally copy the javadoc doc-files from the subprojects, which 43 | // are potentially generated, to the javadocAll directory. Note 44 | // that we use a copy *method* and not a *task* because the inputs 45 | // of copy tasks is determined within the configuration phase. And 46 | // since some of the inputs are generated, they will not get 47 | // picked up if we used a copy method. See also 48 | // https://stackoverflow.com/a/40518516/194894 49 | doLast { 50 | copy { 51 | javadocAllProjects.each { 52 | from ("${it.projectDir}/src/javadoc") { 53 | include '**/doc-files/*.*' 54 | } 55 | } 56 | 57 | into javadocAllDir 58 | } 59 | } 60 | } 61 | 62 | task inttest { 63 | description 'Verify correct functionality by running some integration tests.' 64 | dependsOn project(':minidns-integration-test').tasks.run 65 | } 66 | -------------------------------------------------------------------------------- /config/checkstyle/header.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | -------------------------------------------------------------------------------- /config/checkstyle/suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /gradle.properties.example: -------------------------------------------------------------------------------- 1 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 2 | # 3 | # GPG settings 4 | # 5 | 6 | # gpg key id 7 | #signing.keyId=DEADBEEF 8 | # the gpg key passphrase 9 | #signing.password=correcthorsebatterystaple 10 | # gpg keyring (this is the default gnupg keyring containing private keys) 11 | #signing.secretKeyRingFile=/home/ubuntu/.gnupg/secring.gpg 12 | 13 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 14 | # 15 | # nexus settings 16 | # 17 | 18 | # the nexus username used for log in 19 | #nexusUsername=ubuntu 20 | # the nexus password 21 | #nexusPassword=correcthorsebatterystaple 22 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 74 | 75 | 76 | @rem Execute Gradle 77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 78 | 79 | :end 80 | @rem End local scope for the variables with windows NT shell 81 | if %ERRORLEVEL% equ 0 goto mainEnd 82 | 83 | :fail 84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 85 | rem the _cmd.exe /c_ return code! 86 | set EXIT_CODE=%ERRORLEVEL% 87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 89 | exit /b %EXIT_CODE% 90 | 91 | :mainEnd 92 | if "%OS%"=="Windows_NT" endlocal 93 | 94 | :omega 95 | -------------------------------------------------------------------------------- /minidns-android23/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.minidns.java-conventions' 3 | id 'org.minidns.android-conventions' 4 | } 5 | 6 | ext { 7 | myAndroidSdkApi = 23 8 | androidBootClasspath = getAndroidRuntimeJar(myAndroidSdkApi) 9 | } 10 | 11 | description = "MiniDNS code that requires an Android SDK API of ${myAndroidSdkApi} or higher" 12 | 13 | dependencies { 14 | api project(':minidns-client') 15 | testImplementation project(path: ":minidns-client", configuration: "testRuntime") 16 | 17 | // Add the Android jar to the Eclipse .classpath. 18 | implementation files(androidBootClasspath) 19 | 20 | // For AnimalSniffer 21 | signature "net.sf.androidscents.signature:android-api-level-${myAndroidSdkApi}:6.0_r3@signature" 22 | } 23 | -------------------------------------------------------------------------------- /minidns-android23/src/test/java/org/minidns/dnsserverlookup/android21/AndroidUsingLinkPropertiesTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnsserverlookup.android21; 12 | 13 | import org.junit.jupiter.api.Test; 14 | 15 | public class AndroidUsingLinkPropertiesTest { 16 | 17 | /** 18 | * Dummy test to make jacocoRootReport happy. 19 | */ 20 | @Test 21 | public void nopTest() { 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /minidns-async/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.minidns.java-conventions' 3 | id 'org.minidns.android-conventions' 4 | } 5 | 6 | description = "Asynchronous DNS lookups using Java NIO" 7 | 8 | dependencies { 9 | api project(':minidns-client') 10 | testImplementation project(path: ":minidns-client", configuration: "testRuntime") 11 | } 12 | -------------------------------------------------------------------------------- /minidns-async/src/main/java/org/minidns/source/async/ChannelSelectedHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.source.async; 12 | 13 | import java.io.IOException; 14 | import java.nio.channels.SelectableChannel; 15 | import java.nio.channels.SelectionKey; 16 | import java.util.concurrent.Future; 17 | import java.util.logging.Level; 18 | import java.util.logging.Logger; 19 | 20 | abstract class ChannelSelectedHandler { 21 | 22 | private static final Logger LOGGER = Logger.getLogger(ChannelSelectedHandler.class.getName()); 23 | 24 | final Future future; 25 | 26 | ChannelSelectedHandler(Future future) { 27 | this.future = future; 28 | } 29 | 30 | void handleChannelSelected(SelectableChannel channel, SelectionKey selectionKey) { 31 | if (future.isCancelled()) { 32 | try { 33 | channel.close(); 34 | } catch (IOException e) { 35 | LOGGER.log(Level.INFO, "Could not close channel", e); 36 | } 37 | return; 38 | } 39 | handleChannelSelectedAndNotCancelled(channel, selectionKey); 40 | } 41 | 42 | protected abstract void handleChannelSelectedAndNotCancelled(SelectableChannel channel, SelectionKey selectionKey); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /minidns-async/src/test/java/org/minidns/source/async/AsyncNetworkDataSourceTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.source.async; 12 | 13 | import org.junit.jupiter.api.Test; 14 | 15 | public class AsyncNetworkDataSourceTest { 16 | 17 | /** 18 | * Dummy test to make jacocoRootReport happy. 19 | */ 20 | @Test 21 | public void nopTest() { 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /minidns-client/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.minidns.java-conventions' 3 | id 'org.minidns.android-conventions' 4 | } 5 | 6 | description = "A small non-recursing DNS client" 7 | 8 | dependencies { 9 | api project(':minidns-core') 10 | testImplementation project(path: ":minidns-core", configuration: "testRuntime") 11 | } 12 | 13 | jar { 14 | bundle { 15 | bnd( 16 | // minidns-client invokes Class.forName("android.os.…") 17 | // which causes OSGi to import android.os, because OSGi's 18 | // bnd scans for `Class.forName` usages per default. 19 | // See also https://github.com/openhab/openhab-addons/pull/11670#issuecomment-982539016 20 | '-noclassforname': 'true', 21 | ) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /minidns-client/src/main/java/org/minidns/DnsCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns; 12 | 13 | import org.minidns.dnsmessage.DnsMessage; 14 | import org.minidns.dnsname.DnsName; 15 | import org.minidns.dnsqueryresult.CachedDnsQueryResult; 16 | import org.minidns.dnsqueryresult.DnsQueryResult; 17 | 18 | /** 19 | * Cache for DNS Entries. Implementations must be thread safe. 20 | */ 21 | public abstract class DnsCache { 22 | 23 | public static final int DEFAULT_CACHE_SIZE = 512; 24 | 25 | /** 26 | * Add an an dns answer/response for a given dns question. Implementations 27 | * should honor the ttl / receive timestamp. 28 | * @param query The query message containing a question. 29 | * @param result The DNS query result. 30 | */ 31 | public final void put(DnsMessage query, DnsQueryResult result) { 32 | putNormalized(query.asNormalizedVersion(), result); 33 | } 34 | 35 | protected abstract void putNormalized(DnsMessage normalizedQuery, DnsQueryResult result); 36 | 37 | public abstract void offer(DnsMessage query, DnsQueryResult result, DnsName authoritativeZone); 38 | 39 | /** 40 | * Request a cached dns response. 41 | * @param query The query message containing a question. 42 | * @return The dns message. 43 | */ 44 | public final CachedDnsQueryResult get(DnsMessage query) { 45 | return getNormalized(query.asNormalizedVersion()); 46 | } 47 | 48 | protected abstract CachedDnsQueryResult getNormalized(DnsMessage normalizedQuery); 49 | 50 | } 51 | -------------------------------------------------------------------------------- /minidns-client/src/main/java/org/minidns/MiniDnsConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns; 12 | 13 | public class MiniDnsConfiguration { 14 | 15 | public static String getVersion() { 16 | return MiniDnsInitialization.VERSION; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /minidns-client/src/main/java/org/minidns/MiniDnsInitialization.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns; 12 | 13 | import java.io.BufferedReader; 14 | import java.io.IOException; 15 | import java.io.InputStream; 16 | import java.io.InputStreamReader; 17 | import java.nio.charset.StandardCharsets; 18 | import java.util.logging.Level; 19 | import java.util.logging.Logger; 20 | 21 | public class MiniDnsInitialization { 22 | 23 | private static final Logger LOGGER = Logger.getLogger(MiniDnsInitialization.class.getName()); 24 | 25 | static final String VERSION; 26 | 27 | static { 28 | String miniDnsVersion; 29 | BufferedReader reader = null; 30 | try { 31 | InputStream is = MiniDnsInitialization.class.getClassLoader().getResourceAsStream("org.minidns/version"); 32 | reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); 33 | miniDnsVersion = reader.readLine(); 34 | } catch (Exception e) { 35 | LOGGER.log(Level.SEVERE, "Could not determine MiniDNS version", e); 36 | miniDnsVersion = "unkown"; 37 | } finally { 38 | if (reader != null) { 39 | try { 40 | reader.close(); 41 | } catch (IOException e) { 42 | LOGGER.log(Level.WARNING, "IOException closing stream", e); 43 | } 44 | } 45 | } 46 | VERSION = miniDnsVersion; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /minidns-client/src/main/java/org/minidns/RrSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns; 12 | 13 | import java.util.Collections; 14 | import java.util.LinkedHashSet; 15 | import java.util.Set; 16 | 17 | import org.minidns.dnsname.DnsName; 18 | import org.minidns.record.Data; 19 | import org.minidns.record.Record; 20 | import org.minidns.record.Record.CLASS; 21 | import org.minidns.record.Record.TYPE; 22 | 23 | public final class RrSet { 24 | 25 | public final DnsName name; 26 | public final TYPE type; 27 | public final CLASS clazz; 28 | public final Set> records; 29 | 30 | private RrSet(DnsName name, TYPE type, CLASS clazz, Set> records) { 31 | this.name = name; 32 | this.type = type; 33 | this.clazz = clazz; 34 | this.records = Collections.unmodifiableSet(records); 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | StringBuilder sb = new StringBuilder(); 40 | sb.append(name).append('\t').append(clazz).append('\t').append(type).append('\n'); 41 | for (Record record : records) { 42 | sb.append(record).append('\n'); 43 | } 44 | return sb.toString(); 45 | } 46 | 47 | public static Builder builder() { 48 | return new Builder(); 49 | } 50 | 51 | public static final class Builder { 52 | private DnsName name; 53 | private TYPE type; 54 | private CLASS clazz; 55 | Set> records = new LinkedHashSet<>(8); 56 | 57 | private Builder() { 58 | } 59 | 60 | public Builder addRecord(Record record) { 61 | if (name == null) { 62 | name = record.name; 63 | type = record.type; 64 | clazz = record.clazz; 65 | } else if (!couldContain(record)) { 66 | throw new IllegalArgumentException( 67 | "Can not add " + record + " to RRSet " + name + ' ' + type + ' ' + clazz); 68 | } 69 | 70 | boolean didNotExist = records.add(record); 71 | assert didNotExist; 72 | 73 | return this; 74 | } 75 | 76 | public boolean couldContain(Record record) { 77 | if (name == null) { 78 | return true; 79 | } 80 | return name.equals(record.name) && type == record.type && clazz == record.clazz; 81 | } 82 | 83 | public boolean addIfPossible(Record record) { 84 | if (!couldContain(record)) { 85 | return false; 86 | } 87 | addRecord(record); 88 | return true; 89 | } 90 | 91 | public RrSet build() { 92 | if (name == null) { 93 | // There is no RR added to this builder. 94 | throw new IllegalStateException(); 95 | } 96 | return new RrSet(name, type, clazz, records); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /minidns-client/src/main/java/org/minidns/cache/FullLruCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.cache; 12 | 13 | import org.minidns.dnsmessage.Question; 14 | import org.minidns.dnsname.DnsName; 15 | import org.minidns.record.Data; 16 | import org.minidns.record.Record; 17 | 18 | /** 19 | * An insecure variant of {@link LruCache} also using all the data found in the sections of an answer. 20 | */ 21 | public class FullLruCache extends ExtendedLruCache { 22 | 23 | public FullLruCache() { 24 | this(DEFAULT_CACHE_SIZE); 25 | } 26 | 27 | public FullLruCache(int capacity) { 28 | super(capacity); 29 | } 30 | 31 | public FullLruCache(int capacity, long maxTTL) { 32 | super(capacity, maxTTL); 33 | } 34 | 35 | @Override 36 | protected boolean shouldGather(Record extraRecord, Question question, DnsName authoritativeZone) { 37 | return true; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /minidns-client/src/main/java/org/minidns/cache/MiniDnsCacheFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.cache; 12 | 13 | import org.minidns.DnsCache; 14 | 15 | public interface MiniDnsCacheFactory { 16 | 17 | DnsCache newCache(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /minidns-client/src/main/java/org/minidns/dnsqueryresult/CachedDnsQueryResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnsqueryresult; 12 | 13 | import org.minidns.dnsmessage.DnsMessage; 14 | 15 | public abstract class CachedDnsQueryResult extends DnsQueryResult { 16 | 17 | protected final DnsQueryResult cachedDnsQueryResult; 18 | 19 | protected CachedDnsQueryResult(DnsMessage query, DnsQueryResult cachedDnsQueryResult) { 20 | super(QueryMethod.cachedDirect, query, cachedDnsQueryResult.response); 21 | this.cachedDnsQueryResult = cachedDnsQueryResult; 22 | } 23 | 24 | protected CachedDnsQueryResult(DnsMessage query, DnsMessage response, DnsQueryResult synthesynthesizationSource) { 25 | super(QueryMethod.cachedSynthesized, query, response); 26 | this.cachedDnsQueryResult = synthesynthesizationSource; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /minidns-client/src/main/java/org/minidns/dnsqueryresult/DirectCachedDnsQueryResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnsqueryresult; 12 | 13 | import org.minidns.dnsmessage.DnsMessage; 14 | 15 | public class DirectCachedDnsQueryResult extends CachedDnsQueryResult { 16 | 17 | public DirectCachedDnsQueryResult(DnsMessage query, DnsQueryResult cachedDnsQueryResult) { 18 | super(query, cachedDnsQueryResult); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /minidns-client/src/main/java/org/minidns/dnsqueryresult/DnsQueryResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnsqueryresult; 12 | 13 | import org.minidns.dnsmessage.DnsMessage; 14 | import org.minidns.dnsmessage.DnsMessage.RESPONSE_CODE; 15 | 16 | public abstract class DnsQueryResult { 17 | 18 | public enum QueryMethod { 19 | udp, 20 | tcp, 21 | asyncUdp, 22 | asyncTcp, 23 | cachedDirect, 24 | cachedSynthesized, 25 | testWorld, 26 | } 27 | 28 | public final QueryMethod queryMethod; 29 | 30 | public final DnsMessage query; 31 | 32 | public final DnsMessage response; 33 | 34 | protected DnsQueryResult(QueryMethod queryMethod, DnsMessage query, DnsMessage response) { 35 | assert queryMethod != null; 36 | assert query != null; 37 | assert response != null; 38 | 39 | this.queryMethod = queryMethod; 40 | this.query = query; 41 | this.response = response; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return response.toString(); 47 | } 48 | 49 | public boolean wasSuccessful() { 50 | return response.responseCode == RESPONSE_CODE.NO_ERROR; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /minidns-client/src/main/java/org/minidns/dnsqueryresult/StandardDnsQueryResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnsqueryresult; 12 | 13 | import java.net.InetAddress; 14 | 15 | import org.minidns.dnsmessage.DnsMessage; 16 | 17 | public class StandardDnsQueryResult extends DnsQueryResult { 18 | 19 | public final InetAddress serverAddress; 20 | 21 | public final int port; 22 | 23 | public StandardDnsQueryResult(InetAddress serverAddress, int port, QueryMethod queryMethod, DnsMessage query, DnsMessage responseDnsMessage) { 24 | super(queryMethod, query, responseDnsMessage); 25 | this.serverAddress = serverAddress; 26 | this.port = port; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /minidns-client/src/main/java/org/minidns/dnsqueryresult/SynthesizedCachedDnsQueryResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnsqueryresult; 12 | 13 | import org.minidns.dnsmessage.DnsMessage; 14 | 15 | public class SynthesizedCachedDnsQueryResult extends CachedDnsQueryResult { 16 | 17 | public SynthesizedCachedDnsQueryResult(DnsMessage query, DnsMessage response, DnsQueryResult synthesynthesizationSource) { 18 | super(query, response, synthesynthesizationSource); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /minidns-client/src/main/java/org/minidns/dnsserverlookup/AbstractDnsServerLookupMechanism.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnsserverlookup; 12 | 13 | import java.net.InetAddress; 14 | import java.util.ArrayList; 15 | import java.util.Collection; 16 | import java.util.List; 17 | import java.util.logging.Logger; 18 | 19 | public abstract class AbstractDnsServerLookupMechanism implements DnsServerLookupMechanism { 20 | 21 | protected static final Logger LOGGER = Logger.getLogger(AbstractDnsServerLookupMechanism.class.getName()); 22 | 23 | private final String name; 24 | private final int priority; 25 | 26 | protected AbstractDnsServerLookupMechanism(String name, int priority) { 27 | this.name = name; 28 | this.priority = priority; 29 | } 30 | 31 | @Override 32 | public final String getName() { 33 | return name; 34 | } 35 | 36 | @Override 37 | public final int getPriority() { 38 | return priority; 39 | } 40 | 41 | @Override 42 | public final int compareTo(DnsServerLookupMechanism other) { 43 | int myPriority = getPriority(); 44 | int otherPriority = other.getPriority(); 45 | 46 | return Integer.compare(myPriority, otherPriority); 47 | } 48 | 49 | @Override 50 | public abstract List getDnsServerAddresses(); 51 | 52 | protected static List toListOfStrings(Collection inetAddresses) { 53 | List result = new ArrayList<>(inetAddresses.size()); 54 | for (InetAddress inetAddress : inetAddresses) { 55 | String address = inetAddress.getHostAddress(); 56 | result.add(address); 57 | } 58 | return result; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /minidns-client/src/main/java/org/minidns/dnsserverlookup/DnsServerLookupMechanism.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnsserverlookup; 12 | 13 | import java.util.List; 14 | 15 | public interface DnsServerLookupMechanism extends Comparable { 16 | 17 | String getName(); 18 | 19 | int getPriority(); 20 | 21 | boolean isAvailable(); 22 | 23 | /** 24 | * Returns a List of String representing ideally IP addresses. The list must be modifiable. 25 | *

26 | * Note that the lookup mechanisms are not required to assure that only IP addresses are returned. This verification is performed in 27 | * when using {@link org.minidns.DnsClient#findDNS()}. 28 | *

29 | * 30 | * @return a List of Strings presenting hopefully IP addresses. 31 | */ 32 | List getDnsServerAddresses(); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /minidns-client/src/main/java/org/minidns/source/DnsDataSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.source; 12 | 13 | import java.io.IOException; 14 | import java.net.InetAddress; 15 | 16 | import org.minidns.MiniDnsFuture; 17 | import org.minidns.dnsmessage.DnsMessage; 18 | import org.minidns.dnsqueryresult.DnsQueryResult; 19 | 20 | public interface DnsDataSource { 21 | 22 | DnsQueryResult query(DnsMessage message, InetAddress address, int port) throws IOException; 23 | 24 | MiniDnsFuture queryAsync(DnsMessage message, InetAddress address, int port, OnResponseCallback onResponseCallback); 25 | 26 | int getUdpPayloadSize(); 27 | 28 | /** 29 | * Retrieve the current dns query timeout, in milliseconds. 30 | * 31 | * @return the current dns query timeout in milliseconds. 32 | */ 33 | int getTimeout(); 34 | 35 | /** 36 | * Change the dns query timeout for all future queries. The timeout 37 | * must be specified in milliseconds. 38 | * 39 | * @param timeout new dns query timeout in milliseconds. 40 | */ 41 | void setTimeout(int timeout); 42 | 43 | interface OnResponseCallback { 44 | void onResponse(DnsMessage request, DnsQueryResult result); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /minidns-client/src/main/resources/de.measite.minidns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-client/src/main/resources/de.measite.minidns/.keep -------------------------------------------------------------------------------- /minidns-client/src/test/java/org/minidns/dnsqueryresult/TestWorldDnsQueryResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnsqueryresult; 12 | 13 | import org.minidns.DnsWorld.PreparedResponse; 14 | import org.minidns.dnsmessage.DnsMessage; 15 | 16 | public class TestWorldDnsQueryResult extends DnsQueryResult { 17 | 18 | public final PreparedResponse preparedResponse; 19 | 20 | public TestWorldDnsQueryResult(DnsMessage query, DnsMessage response) { 21 | this(query, response, null); 22 | } 23 | 24 | public TestWorldDnsQueryResult(DnsMessage query, DnsMessage response, PreparedResponse preparedResponse) { 25 | super(QueryMethod.testWorld, query, response); 26 | this.preparedResponse = preparedResponse; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /minidns-client/src/test/java/org/minidns/dnsserverlookup/AndroidUsingExecTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnsserverlookup; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertTrue; 14 | 15 | import java.io.BufferedReader; 16 | import java.io.IOException; 17 | import java.io.Reader; 18 | import java.io.StringReader; 19 | import java.net.UnknownHostException; 20 | import java.util.Set; 21 | 22 | import org.junit.jupiter.api.Test; 23 | 24 | public class AndroidUsingExecTest { 25 | 26 | private static final String PROPS_WITH_NEWLINE = "[property.name]: [\n" + 27 | "]\n"; 28 | 29 | @Test 30 | public void parsePropsWithNewlineTest() throws UnknownHostException, IOException { 31 | Reader reader = new StringReader(PROPS_WITH_NEWLINE); 32 | BufferedReader bufferedReader = new BufferedReader(reader); 33 | 34 | Set servers = AndroidUsingExec.parseProps(bufferedReader, false); 35 | 36 | assertTrue(servers.isEmpty()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /minidns-client/src/test/java/org/minidns/source/NetworkDataSourceTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.source; 12 | 13 | import org.junit.jupiter.api.Test; 14 | import org.minidns.dnsmessage.DnsMessage; 15 | import org.minidns.dnsqueryresult.DnsQueryResult; 16 | 17 | import java.io.IOException; 18 | import java.net.InetAddress; 19 | 20 | import static org.junit.jupiter.api.Assertions.assertEquals; 21 | import static org.junit.jupiter.api.Assertions.assertFalse; 22 | import static org.junit.jupiter.api.Assertions.assertTrue; 23 | 24 | public class NetworkDataSourceTest { 25 | 26 | @Test 27 | public void udpTruncatedTcpFallbackTest() throws IOException { 28 | final int tcpResponseId = 42; 29 | class TestNetworkDataSource extends NetworkDataSource { 30 | boolean lastQueryUdp = false; 31 | 32 | @Override 33 | protected DnsMessage queryUdp(DnsMessage message, InetAddress address, int port) throws IOException { 34 | assertFalse(lastQueryUdp); 35 | lastQueryUdp = true; 36 | DnsMessage.Builder msg = DnsMessage.builder(); 37 | msg.setTruncated(true); 38 | return msg.build(); 39 | } 40 | 41 | @Override 42 | protected DnsMessage queryTcp(DnsMessage message, InetAddress address, int port) throws IOException { 43 | assertTrue(lastQueryUdp); 44 | lastQueryUdp = false; 45 | return DnsMessage.builder().setId(tcpResponseId).build(); 46 | } 47 | } 48 | 49 | TestNetworkDataSource world = new TestNetworkDataSource(); 50 | DnsQueryResult result = world.query(DnsMessage.builder().build(), null, 53); 51 | assertEquals(tcpResponseId, result.response.id); 52 | assertFalse(world.lastQueryUdp); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /minidns-core/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.minidns.java-conventions' 3 | id 'org.minidns.android-conventions' 4 | } 5 | 6 | description = "MiniDNS' core classes and functionality" 7 | 8 | class CreateFileTask extends DefaultTask { 9 | @Input 10 | String fileContent 11 | 12 | @OutputFile 13 | File outputFile 14 | 15 | @TaskAction 16 | def createFile() { 17 | outputFile.text = fileContent 18 | } 19 | } 20 | 21 | task createVersionResource(type: CreateFileTask) { 22 | fileContent = version + ' (' + gitCommit + ')' 23 | outputFile = new File(projectDir, 'src/main/resources/org.minidns/version') 24 | } 25 | 26 | processResources.dependsOn(createVersionResource) 27 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/dnslabel/ALabel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnslabel; 12 | 13 | import org.minidns.idna.MiniDnsIdna; 14 | 15 | public final class ALabel extends XnLabel { 16 | 17 | ALabel(String label) { 18 | super(label); 19 | } 20 | 21 | @Override 22 | protected String getInternationalizedRepresentationInternal() { 23 | return MiniDnsIdna.toUnicode(label); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/dnslabel/FakeALabel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnslabel; 12 | 13 | public final class FakeALabel extends XnLabel { 14 | 15 | FakeALabel(String label) { 16 | super(label); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/dnslabel/LdhLabel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnslabel; 12 | 13 | /** 14 | * A LDH (Letters, Digits, Hyphen) label, which is the 15 | * classical label form. 16 | *

17 | * Note that it is a common misconception that LDH labels can not start with a 18 | * digit. The origin of this misconception is likely that 19 | * RFC 1034 20 | * § 3.5 specified 21 | *

22 | *
23 | * They [i.e, DNS labels] must start with a letter, end with a letter or digit, 24 | * and have as interior characters only letters, digits, and hyphen. 25 | *
. 26 | * However, this was relaxed in 27 | * RFC 1123 § 28 | * 2.1 29 | *
30 | * One aspect of host name syntax is hereby changed: the restriction on the first 31 | * character is relaxed to allow either a letter or a digit. 32 | *
33 | * and later summarized in 34 | * RFC 3696 § 35 | * 2: 36 | *
37 | * If the hyphen is used, it is not permitted to appear at either the beginning 38 | * or end of a label. 39 | *
40 | * Furthermore 41 | * RFC 42 | * 5890 § 2.3.1 only mentions the requirement that hyphen must not be the 43 | * first or last character of a LDH label. 44 | * 45 | * @see RFC 5890 § 46 | * 2.3.1. LDH Label 47 | * 48 | */ 49 | public abstract class LdhLabel extends DnsLabel { 50 | 51 | protected LdhLabel(String label) { 52 | super(label); 53 | } 54 | 55 | public static boolean isLdhLabel(String label) { 56 | if (label.isEmpty()) { 57 | return false; 58 | } 59 | 60 | if (LeadingOrTrailingHyphenLabel.isLeadingOrTrailingHypenLabelInternal(label)) { 61 | return false; 62 | } 63 | 64 | return consistsOnlyOfLettersDigitsAndHypen(label); 65 | } 66 | 67 | protected static LdhLabel fromInternal(String label) { 68 | assert isLdhLabel(label); 69 | 70 | if (ReservedLdhLabel.isReservedLdhLabel(label)) { 71 | // Label starts with '??--'. Now let us see if it is a XN-Label, starting with 'xn--', but be aware that the 72 | // 'xn' part is case insensitive. The XnLabel.isXnLabelInternal(String) method takes care of this. 73 | if (XnLabel.isXnLabelInternal(label)) { 74 | return XnLabel.fromInternal(label); 75 | } else { 76 | return new ReservedLdhLabel(label); 77 | } 78 | } 79 | return new NonReservedLdhLabel(label); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/dnslabel/LeadingOrTrailingHyphenLabel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnslabel; 12 | 13 | /** 14 | * A DNS label with a leading or trailing hyphen ('-'). 15 | */ 16 | public final class LeadingOrTrailingHyphenLabel extends NonLdhLabel { 17 | 18 | LeadingOrTrailingHyphenLabel(String label) { 19 | super(label); 20 | } 21 | 22 | static boolean isLeadingOrTrailingHypenLabelInternal(String label) { 23 | if (label.isEmpty()) { 24 | return false; 25 | } 26 | 27 | if (label.charAt(0) == '-') { 28 | return true; 29 | } 30 | 31 | if (label.charAt(label.length() - 1) == '-') { 32 | return true; 33 | } 34 | 35 | return false; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/dnslabel/NonLdhLabel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnslabel; 12 | 13 | /** 14 | * A DNS label which contains more than just letters, digits and a hyphen. 15 | * 16 | */ 17 | public abstract class NonLdhLabel extends DnsLabel { 18 | 19 | protected NonLdhLabel(String label) { 20 | super(label); 21 | } 22 | 23 | protected static DnsLabel fromInternal(String label) { 24 | if (UnderscoreLabel.isUnderscoreLabelInternal(label)) { 25 | return new UnderscoreLabel(label); 26 | } 27 | 28 | if (LeadingOrTrailingHyphenLabel.isLeadingOrTrailingHypenLabelInternal(label)) { 29 | return new LeadingOrTrailingHyphenLabel(label); 30 | } 31 | 32 | return new OtherNonLdhLabel(label); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/dnslabel/NonReservedLdhLabel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnslabel; 12 | 13 | /** 14 | * A Non-Reserved LDH label (NR-LDH label), which do not have "--" in the third and fourth position. 15 | * 16 | */ 17 | public final class NonReservedLdhLabel extends LdhLabel { 18 | 19 | NonReservedLdhLabel(String label) { 20 | super(label); 21 | assert isNonReservedLdhLabelInternal(label); 22 | } 23 | 24 | public static boolean isNonReservedLdhLabel(String label) { 25 | if (!isLdhLabel(label)) { 26 | return false; 27 | } 28 | return isNonReservedLdhLabelInternal(label); 29 | } 30 | 31 | static boolean isNonReservedLdhLabelInternal(String label) { 32 | return !ReservedLdhLabel.isReservedLdhLabelInternal(label); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/dnslabel/OtherNonLdhLabel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnslabel; 12 | 13 | /** 14 | * A Non-LDH label which does not begin with an underscore ('_'), hyphen ('-') or ends with an hyphen. 15 | * 16 | */ 17 | public final class OtherNonLdhLabel extends NonLdhLabel { 18 | 19 | OtherNonLdhLabel(String label) { 20 | super(label); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/dnslabel/ReservedLdhLabel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnslabel; 12 | 13 | /** 14 | * A reserved LDH label (R-LDH label), which have the property that they contain "--" in the third and fourth characters. 15 | * 16 | */ 17 | public class ReservedLdhLabel extends LdhLabel { 18 | 19 | protected ReservedLdhLabel(String label) { 20 | super(label); 21 | assert isReservedLdhLabelInternal(label); 22 | } 23 | 24 | public static boolean isReservedLdhLabel(String label) { 25 | if (!isLdhLabel(label)) { 26 | return false; 27 | } 28 | return isReservedLdhLabelInternal(label); 29 | } 30 | 31 | static boolean isReservedLdhLabelInternal(String label) { 32 | return label.length() >= 4 33 | && label.charAt(2) == '-' 34 | && label.charAt(3) == '-'; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/dnslabel/UnderscoreLabel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnslabel; 12 | 13 | /** 14 | * A DNS label which begins with an underscore ('_'). 15 | * 16 | */ 17 | public final class UnderscoreLabel extends NonLdhLabel { 18 | 19 | UnderscoreLabel(String label) { 20 | super(label); 21 | } 22 | 23 | static boolean isUnderscoreLabelInternal(String label) { 24 | return label.charAt(0) == '_'; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/dnslabel/XnLabel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnslabel; 12 | 13 | import java.util.Locale; 14 | 15 | import org.minidns.idna.MiniDnsIdna; 16 | 17 | /** 18 | * A label that begins with "xn--" and follows the LDH rule. 19 | */ 20 | public abstract class XnLabel extends ReservedLdhLabel { 21 | 22 | protected XnLabel(String label) { 23 | super(label); 24 | } 25 | 26 | protected static LdhLabel fromInternal(String label) { 27 | assert isIdnAcePrefixed(label); 28 | 29 | String uLabel = MiniDnsIdna.toUnicode(label); 30 | if (label.equals(uLabel)) { 31 | // No Punycode conversation to Unicode was performed, this is a fake A-label! 32 | return new FakeALabel(label); 33 | } else { 34 | return new ALabel(label); 35 | } 36 | } 37 | 38 | public static boolean isXnLabel(String label) { 39 | if (!isReservedLdhLabel(label)) { 40 | return false; 41 | } 42 | return isXnLabelInternal(label); 43 | } 44 | 45 | static boolean isXnLabelInternal(String label) { 46 | // Note that we already ensure the minimum label length here, since reserved LDH 47 | // labels must start with "xn--". 48 | return label.substring(0, 2).toLowerCase(Locale.US).equals("xn"); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/dnsname/InvalidDnsNameException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnsname; 12 | 13 | import org.minidns.dnslabel.DnsLabel; 14 | 15 | public abstract class InvalidDnsNameException extends IllegalStateException { 16 | 17 | private static final long serialVersionUID = 1L; 18 | 19 | protected final String ace; 20 | 21 | protected InvalidDnsNameException(String ace) { 22 | this.ace = ace; 23 | } 24 | 25 | public static class LabelTooLongException extends InvalidDnsNameException { 26 | /** 27 | * 28 | */ 29 | private static final long serialVersionUID = 1L; 30 | 31 | private final String label; 32 | 33 | public LabelTooLongException(String ace, String label) { 34 | super(ace); 35 | this.label = label; 36 | } 37 | 38 | @Override 39 | public String getMessage() { 40 | return "The DNS name '" + ace + "' contains the label '" + label 41 | + "' which exceeds the maximum label length of " + DnsLabel.MAX_LABEL_LENGTH_IN_OCTETS + " octets by " 42 | + (label.length() - DnsLabel.MAX_LABEL_LENGTH_IN_OCTETS) + " octets."; 43 | } 44 | } 45 | 46 | public static class DNSNameTooLongException extends InvalidDnsNameException { 47 | /** 48 | * 49 | */ 50 | private static final long serialVersionUID = 1L; 51 | 52 | private final byte[] bytes; 53 | 54 | public DNSNameTooLongException(String ace, byte[] bytes) { 55 | super(ace); 56 | this.bytes = bytes; 57 | } 58 | 59 | @Override 60 | public String getMessage() { 61 | return "The DNS name '" + ace + "' exceeds the maximum name length of " 62 | + DnsName.MAX_DNSNAME_LENGTH_IN_OCTETS + " octets by " 63 | + (bytes.length - DnsName.MAX_DNSNAME_LENGTH_IN_OCTETS) + " octets."; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/edns/EdnsOption.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.edns; 12 | 13 | import java.io.DataOutputStream; 14 | import java.io.IOException; 15 | 16 | import org.minidns.edns.Edns.OptionCode; 17 | 18 | public abstract class EdnsOption { 19 | 20 | public final int optionCode; 21 | public final int optionLength; 22 | 23 | protected final byte[] optionData; 24 | 25 | protected EdnsOption(int optionCode, byte[] optionData) { 26 | this.optionCode = optionCode; 27 | this.optionLength = optionData.length; 28 | this.optionData = optionData; 29 | } 30 | 31 | @SuppressWarnings("this-escape") 32 | protected EdnsOption(byte[] optionData) { 33 | this.optionCode = getOptionCode().asInt; 34 | this.optionLength = optionData.length; 35 | this.optionData = optionData; 36 | } 37 | 38 | public final void writeToDos(DataOutputStream dos) throws IOException { 39 | dos.writeShort(optionCode); 40 | dos.writeShort(optionLength); 41 | dos.write(optionData); 42 | } 43 | 44 | public abstract OptionCode getOptionCode(); 45 | 46 | private String toStringCache; 47 | 48 | @Override 49 | public final String toString() { 50 | if (toStringCache == null) { 51 | toStringCache = toStringInternal().toString(); 52 | } 53 | return toStringCache; 54 | } 55 | 56 | protected abstract CharSequence toStringInternal(); 57 | 58 | private String terminalOutputCache; 59 | 60 | public final String asTerminalOutput() { 61 | if (terminalOutputCache == null) { 62 | terminalOutputCache = asTerminalOutputInternal().toString(); 63 | } 64 | return terminalOutputCache; 65 | } 66 | 67 | protected abstract CharSequence asTerminalOutputInternal(); 68 | 69 | public static EdnsOption parse(int intOptionCode, byte[] optionData) { 70 | OptionCode optionCode = OptionCode.from(intOptionCode); 71 | EdnsOption res; 72 | switch (optionCode) { 73 | case NSID: 74 | res = new Nsid(optionData); 75 | break; 76 | default: 77 | res = new UnknownEdnsOption(intOptionCode, optionData); 78 | break; 79 | } 80 | return res; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/edns/Nsid.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.edns; 12 | 13 | import java.nio.charset.StandardCharsets; 14 | 15 | import org.minidns.edns.Edns.OptionCode; 16 | import org.minidns.util.Hex; 17 | 18 | public class Nsid extends EdnsOption { 19 | 20 | public static final Nsid REQUEST = new Nsid(); 21 | 22 | private Nsid() { 23 | this(new byte[0]); 24 | } 25 | 26 | public Nsid(byte[] payload) { 27 | super(payload); 28 | } 29 | 30 | @Override 31 | public OptionCode getOptionCode() { 32 | return OptionCode.NSID; 33 | } 34 | 35 | @Override 36 | protected CharSequence toStringInternal() { 37 | String res = OptionCode.NSID + ": "; 38 | res += new String(optionData, StandardCharsets.US_ASCII); 39 | return res; 40 | } 41 | 42 | @Override 43 | protected CharSequence asTerminalOutputInternal() { 44 | return Hex.from(optionData); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/edns/UnknownEdnsOption.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.edns; 12 | 13 | import org.minidns.edns.Edns.OptionCode; 14 | import org.minidns.util.Hex; 15 | 16 | public class UnknownEdnsOption extends EdnsOption { 17 | 18 | protected UnknownEdnsOption(int optionCode, byte[] optionData) { 19 | super(optionCode, optionData); 20 | } 21 | 22 | @Override 23 | public OptionCode getOptionCode() { 24 | return OptionCode.UNKNOWN; 25 | } 26 | 27 | @Override 28 | protected CharSequence asTerminalOutputInternal() { 29 | return Hex.from(optionData); 30 | } 31 | 32 | @Override 33 | protected CharSequence toStringInternal() { 34 | return asTerminalOutputInternal(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/idna/DefaultIdnaTransformator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.idna; 12 | 13 | import java.net.IDN; 14 | 15 | import org.minidns.dnsname.DnsName; 16 | 17 | public class DefaultIdnaTransformator implements IdnaTransformator { 18 | 19 | @Override 20 | public String toASCII(String input) { 21 | // Special case if input is ".", i.e. a string containing only a single dot character. This is a workaround for 22 | // IDN.toASCII() implementations throwing an IllegalArgumentException on this input string (for example Android 23 | // APIs level 26, see https://issuetracker.google.com/issues/113070416). 24 | if (DnsName.ROOT.ace.equals(input)) { 25 | return DnsName.ROOT.ace; 26 | } 27 | 28 | return IDN.toASCII(input); 29 | } 30 | 31 | @Override 32 | public String toUnicode(String input) { 33 | return IDN.toUnicode(input); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/idna/IdnaTransformator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.idna; 12 | 13 | public interface IdnaTransformator { 14 | 15 | String toASCII(String input); 16 | 17 | String toUnicode(String input); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/idna/MiniDnsIdna.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.idna; 12 | 13 | public class MiniDnsIdna { 14 | 15 | private static IdnaTransformator idnaTransformator = new DefaultIdnaTransformator(); 16 | 17 | public static String toASCII(String string) { 18 | return idnaTransformator.toASCII(string); 19 | } 20 | 21 | public static String toUnicode(String string) { 22 | return idnaTransformator.toUnicode(string); 23 | } 24 | 25 | public static void setActiveTransformator(IdnaTransformator idnaTransformator) { 26 | if (idnaTransformator == null) { 27 | throw new IllegalArgumentException(); 28 | } 29 | MiniDnsIdna.idnaTransformator = idnaTransformator; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/A.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import java.io.DataInputStream; 14 | import java.io.IOException; 15 | import java.net.Inet4Address; 16 | 17 | import org.minidns.record.Record.TYPE; 18 | import org.minidns.util.InetAddressUtil; 19 | 20 | /** 21 | * A record payload (ip pointer). 22 | */ 23 | public class A extends InternetAddressRR { 24 | 25 | @Override 26 | public TYPE getType() { 27 | return TYPE.A; 28 | } 29 | 30 | public A(Inet4Address inet4Address) { 31 | super(inet4Address); 32 | assert ip.length == 4; 33 | } 34 | 35 | public A(int q1, int q2, int q3, int q4) { 36 | super(new byte[] { (byte) q1, (byte) q2, (byte) q3, (byte) q4 }); 37 | if (q1 < 0 || q1 > 255 || q2 < 0 || q2 > 255 || q3 < 0 || q3 > 255 || q4 < 0 || q4 > 255) { 38 | throw new IllegalArgumentException(); 39 | } 40 | } 41 | 42 | public A(byte[] ip) { 43 | super(ip); 44 | if (ip.length != 4) { 45 | throw new IllegalArgumentException("IPv4 address in A record is always 4 byte"); 46 | } 47 | } 48 | 49 | public A(CharSequence ipv4CharSequence) { 50 | this(InetAddressUtil.ipv4From(ipv4CharSequence)); 51 | } 52 | 53 | public static A parse(DataInputStream dis) 54 | throws IOException { 55 | byte[] ip = new byte[4]; 56 | dis.readFully(ip); 57 | return new A(ip); 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return Integer.toString(ip[0] & 0xff) + "." + 63 | Integer.toString(ip[1] & 0xff) + "." + 64 | Integer.toString(ip[2] & 0xff) + "." + 65 | Integer.toString(ip[3] & 0xff); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/AAAA.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import java.io.DataInputStream; 14 | import java.io.IOException; 15 | import java.net.Inet6Address; 16 | 17 | import org.minidns.record.Record.TYPE; 18 | import org.minidns.util.InetAddressUtil; 19 | 20 | /** 21 | * AAAA payload (an ipv6 pointer). 22 | */ 23 | public class AAAA extends InternetAddressRR { 24 | 25 | @Override 26 | public TYPE getType() { 27 | return TYPE.AAAA; 28 | } 29 | 30 | public AAAA(Inet6Address inet6address) { 31 | super(inet6address); 32 | assert ip.length == 16; 33 | } 34 | 35 | public AAAA(byte[] ip) { 36 | super(ip); 37 | if (ip.length != 16) { 38 | throw new IllegalArgumentException("IPv6 address in AAAA record is always 16 byte"); 39 | } 40 | } 41 | 42 | public AAAA(CharSequence ipv6CharSequence) { 43 | this(InetAddressUtil.ipv6From(ipv6CharSequence)); 44 | } 45 | 46 | public static AAAA parse(DataInputStream dis) 47 | throws IOException { 48 | byte[] ip = new byte[16]; 49 | dis.readFully(ip); 50 | return new AAAA(ip); 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | StringBuilder sb = new StringBuilder(); 56 | for (int i = 0; i < ip.length; i += 2) { 57 | if (i != 0) { 58 | sb.append(':'); 59 | } 60 | sb.append(Integer.toHexString( 61 | ((ip[i] & 0xff) << 8) + (ip[i + 1] & 0xff) 62 | )); 63 | } 64 | return sb.toString(); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/CNAME.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import org.minidns.dnsname.DnsName; 14 | import org.minidns.record.Record.TYPE; 15 | 16 | import java.io.DataInputStream; 17 | import java.io.IOException; 18 | 19 | /** 20 | * CNAME payload (pointer to another domain / address). 21 | */ 22 | public class CNAME extends RRWithTarget { 23 | 24 | public static CNAME parse(DataInputStream dis, byte[] data) throws IOException { 25 | DnsName target = DnsName.parse(dis, data); 26 | return new CNAME(target); 27 | } 28 | 29 | public CNAME(String target) { 30 | this(DnsName.from(target)); 31 | } 32 | 33 | public CNAME(DnsName target) { 34 | super(target); 35 | } 36 | 37 | @Override 38 | public TYPE getType() { 39 | return TYPE.CNAME; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/DLV.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import java.io.DataInputStream; 14 | import java.io.IOException; 15 | 16 | import org.minidns.constants.DnssecConstants.DigestAlgorithm; 17 | import org.minidns.constants.DnssecConstants.SignatureAlgorithm; 18 | 19 | /** 20 | * DLV record payload. 21 | * 22 | * According to RFC4431, DLV has exactly the same format as DS records. 23 | */ 24 | public class DLV extends DelegatingDnssecRR { 25 | 26 | public static DLV parse (DataInputStream dis, int length) throws IOException { 27 | SharedData parsedData = DelegatingDnssecRR.parseSharedData(dis, length); 28 | return new DLV(parsedData.keyTag, parsedData.algorithm, parsedData.digestType, parsedData.digest); 29 | } 30 | 31 | public DLV(int keyTag, byte algorithm, byte digestType, byte[] digest) { 32 | super(keyTag, algorithm, digestType, digest); 33 | } 34 | 35 | public DLV(int keyTag, SignatureAlgorithm algorithm, DigestAlgorithm digestType, byte[] digest) { 36 | super(keyTag, algorithm, digestType, digest); 37 | } 38 | 39 | @Override 40 | public Record.TYPE getType() { 41 | return Record.TYPE.DLV; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/DNAME.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import org.minidns.dnsname.DnsName; 14 | import org.minidns.record.Record.TYPE; 15 | 16 | import java.io.DataInputStream; 17 | import java.io.IOException; 18 | 19 | /** 20 | * A DNAME resource record. 21 | * 22 | * @see RFC 6672 - DNAME Redirection in the DNS 23 | */ 24 | public class DNAME extends RRWithTarget { 25 | 26 | public static DNAME parse(DataInputStream dis, byte[] data) throws IOException { 27 | DnsName target = DnsName.parse(dis, data); 28 | return new DNAME(target); 29 | } 30 | 31 | public DNAME(String target) { 32 | this(DnsName.from(target)); 33 | } 34 | 35 | public DNAME(DnsName target) { 36 | super(target); 37 | } 38 | 39 | @Override 40 | public TYPE getType() { 41 | return TYPE.DNAME; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/DS.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import org.minidns.constants.DnssecConstants.DigestAlgorithm; 14 | import org.minidns.constants.DnssecConstants.SignatureAlgorithm; 15 | import org.minidns.record.Record.TYPE; 16 | 17 | import java.io.DataInputStream; 18 | import java.io.IOException; 19 | /** 20 | * DS (Delegation Signer) record payload. 21 | * 22 | * @see RFC 4034 § 5 23 | */ 24 | public class DS extends DelegatingDnssecRR { 25 | 26 | public static DS parse(DataInputStream dis, int length) throws IOException { 27 | SharedData parsedData = DelegatingDnssecRR.parseSharedData(dis, length); 28 | return new DS(parsedData.keyTag, parsedData.algorithm, parsedData.digestType, parsedData.digest); 29 | } 30 | 31 | public DS(int keyTag, byte algorithm, byte digestType, byte[] digest) { 32 | super(keyTag, algorithm, digestType, digest); 33 | } 34 | 35 | public DS(int keyTag, SignatureAlgorithm algorithm, byte digestType, byte[] digest) { 36 | super(keyTag, algorithm, digestType, digest); 37 | } 38 | 39 | public DS(int keyTag, SignatureAlgorithm algorithm, DigestAlgorithm digestType, byte[] digest) { 40 | super(keyTag, algorithm, digestType, digest); 41 | } 42 | 43 | @Override 44 | public TYPE getType() { 45 | return TYPE.DS; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/Data.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import java.io.ByteArrayOutputStream; 14 | import java.io.DataOutputStream; 15 | import java.io.IOException; 16 | import java.io.OutputStream; 17 | import java.util.Arrays; 18 | 19 | import org.minidns.record.Record.TYPE; 20 | 21 | /** 22 | * Generic payload class. 23 | */ 24 | public abstract class Data { 25 | 26 | /** 27 | * The payload type. 28 | * @return The payload type. 29 | */ 30 | public abstract TYPE getType(); 31 | 32 | /** 33 | * The internal method used to serialize Data subclasses. 34 | * 35 | * @param dos the output stream to serialize to. 36 | * @throws IOException if an I/O error occurs. 37 | */ 38 | protected abstract void serialize(DataOutputStream dos) throws IOException; 39 | 40 | private byte[] bytes; 41 | 42 | private void setBytes() { 43 | if (bytes != null) return; 44 | 45 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 46 | DataOutputStream dos = new DataOutputStream(baos); 47 | try { 48 | serialize(dos); 49 | } catch (IOException e) { 50 | // Should never happen. 51 | throw new AssertionError(e); 52 | } 53 | bytes = baos.toByteArray(); 54 | } 55 | 56 | public final int length() { 57 | setBytes(); 58 | return bytes.length; 59 | } 60 | 61 | public final void toOutputStream(OutputStream outputStream) throws IOException { 62 | DataOutputStream dataOutputStream = new DataOutputStream(outputStream); 63 | toOutputStream(dataOutputStream); 64 | } 65 | 66 | /** 67 | * Write the binary representation of this payload to the given {@link DataOutputStream}. 68 | * 69 | * @param dos the DataOutputStream to write to. 70 | * @throws IOException if an I/O error occurs. 71 | */ 72 | public final void toOutputStream(DataOutputStream dos) throws IOException { 73 | setBytes(); 74 | dos.write(bytes); 75 | } 76 | 77 | public final byte[] toByteArray() { 78 | setBytes(); 79 | return bytes.clone(); 80 | } 81 | 82 | private transient Integer hashCodeCache; 83 | 84 | @Override 85 | public final int hashCode() { 86 | if (hashCodeCache == null) { 87 | setBytes(); 88 | hashCodeCache = Arrays.hashCode(bytes); 89 | } 90 | return hashCodeCache; 91 | } 92 | 93 | @Override 94 | public final boolean equals(Object other) { 95 | if (!(other instanceof Data)) { 96 | return false; 97 | } 98 | if (other == this) { 99 | return true; 100 | } 101 | Data otherData = (Data) other; 102 | otherData.setBytes(); 103 | setBytes(); 104 | 105 | return Arrays.equals(bytes, otherData.bytes); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/InternetAddressRR.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import java.io.DataOutputStream; 14 | import java.io.IOException; 15 | import java.net.Inet4Address; 16 | import java.net.Inet6Address; 17 | import java.net.InetAddress; 18 | import java.net.UnknownHostException; 19 | 20 | /** 21 | * A resource record representing a internet address. Provides {@link #getInetAddress()}. 22 | */ 23 | public abstract class InternetAddressRR extends Data { 24 | 25 | 26 | /** 27 | * Target IP. 28 | */ 29 | protected final byte[] ip; 30 | 31 | /** 32 | * Cache for the {@link InetAddress} this record presents. 33 | */ 34 | private transient IA inetAddress; 35 | 36 | protected InternetAddressRR(byte[] ip) { 37 | this.ip = ip; 38 | } 39 | 40 | protected InternetAddressRR(IA inetAddress) { 41 | this(inetAddress.getAddress()); 42 | this.inetAddress = inetAddress; 43 | } 44 | 45 | @Override 46 | public final void serialize(DataOutputStream dos) throws IOException { 47 | dos.write(ip); 48 | } 49 | 50 | /** 51 | * Allocates a new byte buffer and fills the buffer with the bytes representing the IP address of this resource record. 52 | * 53 | * @return a new byte buffer containing the bytes of the IP. 54 | */ 55 | public final byte[] getIp() { 56 | return ip.clone(); 57 | } 58 | 59 | @SuppressWarnings("unchecked") 60 | public final IA getInetAddress() { 61 | if (inetAddress == null) { 62 | try { 63 | inetAddress = (IA) InetAddress.getByAddress(ip); 64 | } catch (UnknownHostException e) { 65 | throw new IllegalStateException(e); 66 | } 67 | } 68 | return inetAddress; 69 | } 70 | 71 | public static InternetAddressRR from(InetAddress inetAddress) { 72 | if (inetAddress instanceof Inet4Address) { 73 | return new A((Inet4Address) inetAddress); 74 | } 75 | 76 | return new AAAA((Inet6Address) inetAddress); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/MX.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import java.io.DataInputStream; 14 | import java.io.DataOutputStream; 15 | import java.io.IOException; 16 | 17 | import org.minidns.dnsname.DnsName; 18 | import org.minidns.record.Record.TYPE; 19 | 20 | /** 21 | * MX record payload (mail service pointer). 22 | */ 23 | public class MX extends Data { 24 | 25 | /** 26 | * The priority of this service. Lower values mean higher priority. 27 | */ 28 | public final int priority; 29 | 30 | /** 31 | * The name of the target server. 32 | */ 33 | public final DnsName target; 34 | 35 | /** 36 | * The name of the target server. 37 | * 38 | * @deprecated use {@link #target} instead. 39 | */ 40 | @Deprecated 41 | public final DnsName name; 42 | 43 | public static MX parse(DataInputStream dis, byte[] data) 44 | throws IOException { 45 | int priority = dis.readUnsignedShort(); 46 | DnsName name = DnsName.parse(dis, data); 47 | return new MX(priority, name); 48 | } 49 | 50 | public MX(int priority, String name) { 51 | this(priority, DnsName.from(name)); 52 | } 53 | 54 | public MX(int priority, DnsName name) { 55 | this.priority = priority; 56 | this.target = name; 57 | this.name = target; 58 | } 59 | 60 | @Override 61 | public void serialize(DataOutputStream dos) throws IOException { 62 | dos.writeShort(priority); 63 | target.writeToStream(dos); 64 | } 65 | 66 | @Override 67 | public String toString() { 68 | return priority + " " + target + '.'; 69 | } 70 | 71 | @Override 72 | public TYPE getType() { 73 | return TYPE.MX; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/NS.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import java.io.DataInputStream; 14 | import java.io.IOException; 15 | 16 | import org.minidns.dnsname.DnsName; 17 | import org.minidns.record.Record.TYPE; 18 | 19 | /** 20 | * Nameserver record. 21 | */ 22 | public class NS extends RRWithTarget { 23 | 24 | public static NS parse(DataInputStream dis, byte[] data) throws IOException { 25 | DnsName target = DnsName.parse(dis, data); 26 | return new NS(target); 27 | } 28 | 29 | public NS(DnsName name) { 30 | super(name); 31 | } 32 | 33 | @Override 34 | public TYPE getType() { 35 | return TYPE.NS; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/OPENPGPKEY.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import org.minidns.util.Base64; 14 | 15 | import java.io.DataInputStream; 16 | import java.io.DataOutputStream; 17 | import java.io.IOException; 18 | 19 | public class OPENPGPKEY extends Data { 20 | 21 | private final byte[] publicKeyPacket; 22 | 23 | public static OPENPGPKEY parse(DataInputStream dis, int length) throws IOException { 24 | byte[] publicKeyPacket = new byte[length]; 25 | dis.readFully(publicKeyPacket); 26 | return new OPENPGPKEY(publicKeyPacket); 27 | } 28 | 29 | OPENPGPKEY(byte[] publicKeyPacket) { 30 | this.publicKeyPacket = publicKeyPacket; 31 | } 32 | 33 | @Override 34 | public Record.TYPE getType() { 35 | return Record.TYPE.OPENPGPKEY; 36 | } 37 | 38 | @Override 39 | public void serialize(DataOutputStream dos) throws IOException { 40 | dos.write(publicKeyPacket); 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return getPublicKeyPacketBase64(); 46 | } 47 | 48 | private transient String publicKeyPacketBase64Cache; 49 | 50 | public String getPublicKeyPacketBase64() { 51 | if (publicKeyPacketBase64Cache == null) { 52 | publicKeyPacketBase64Cache = Base64.encodeToString(publicKeyPacket); 53 | } 54 | return publicKeyPacketBase64Cache; 55 | } 56 | 57 | public byte[] getPublicKeyPacket() { 58 | return publicKeyPacket.clone(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/OPT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import org.minidns.edns.EdnsOption; 14 | import org.minidns.record.Record.TYPE; 15 | 16 | import java.io.DataInputStream; 17 | import java.io.DataOutputStream; 18 | import java.io.IOException; 19 | import java.util.ArrayList; 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | /** 24 | * OPT payload (see RFC 2671 for details). 25 | */ 26 | public class OPT extends Data { 27 | 28 | public final List variablePart; 29 | 30 | public OPT() { 31 | this(Collections.emptyList()); 32 | } 33 | 34 | public OPT(List variablePart) { 35 | this.variablePart = Collections.unmodifiableList(variablePart); 36 | } 37 | 38 | public static OPT parse(DataInputStream dis, int payloadLength) throws IOException { 39 | List variablePart; 40 | if (payloadLength == 0) { 41 | variablePart = Collections.emptyList(); 42 | } else { 43 | int payloadLeft = payloadLength; 44 | variablePart = new ArrayList<>(4); 45 | while (payloadLeft > 0) { 46 | int optionCode = dis.readUnsignedShort(); 47 | int optionLength = dis.readUnsignedShort(); 48 | byte[] optionData = new byte[optionLength]; 49 | dis.read(optionData); 50 | EdnsOption ednsOption = EdnsOption.parse(optionCode, optionData); 51 | variablePart.add(ednsOption); 52 | payloadLeft -= 2 + 2 + optionLength; 53 | // Assert that payloadLeft never becomes negative 54 | assert payloadLeft >= 0; 55 | } 56 | } 57 | return new OPT(variablePart); 58 | } 59 | 60 | @Override 61 | public TYPE getType() { 62 | return TYPE.OPT; 63 | } 64 | 65 | @Override 66 | protected void serialize(DataOutputStream dos) throws IOException { 67 | for (EdnsOption endsOption : variablePart) { 68 | endsOption.writeToDos(dos); 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/PTR.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import java.io.DataInputStream; 14 | import java.io.IOException; 15 | 16 | import org.minidns.dnsname.DnsName; 17 | import org.minidns.record.Record.TYPE; 18 | 19 | /** 20 | * A PTR record is handled like a CNAME. 21 | */ 22 | public class PTR extends RRWithTarget { 23 | 24 | public static PTR parse(DataInputStream dis, byte[] data) throws IOException { 25 | DnsName target = DnsName.parse(dis, data); 26 | return new PTR(target); 27 | } 28 | 29 | PTR(String name) { 30 | this(DnsName.from(name)); 31 | } 32 | 33 | PTR(DnsName name) { 34 | super(name); 35 | } 36 | 37 | @Override 38 | public TYPE getType() { 39 | return TYPE.PTR; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/RRWithTarget.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import java.io.DataOutputStream; 14 | import java.io.IOException; 15 | 16 | import org.minidns.dnsname.DnsName; 17 | 18 | /** 19 | * A resource record pointing to a target. 20 | */ 21 | public abstract class RRWithTarget extends Data { 22 | 23 | public final DnsName target; 24 | 25 | /** 26 | * The target of this resource record. 27 | * @deprecated {@link #target} instead. 28 | */ 29 | @Deprecated 30 | public final DnsName name; 31 | 32 | @Override 33 | public void serialize(DataOutputStream dos) throws IOException { 34 | target.writeToStream(dos); 35 | } 36 | 37 | protected RRWithTarget(DnsName target) { 38 | this.target = target; 39 | this.name = target; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return target + "."; 45 | } 46 | 47 | public final DnsName getTarget() { 48 | return target; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/SRV.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import java.io.DataInputStream; 14 | import java.io.DataOutputStream; 15 | import java.io.IOException; 16 | 17 | import org.minidns.dnsname.DnsName; 18 | import org.minidns.record.Record.TYPE; 19 | 20 | /** 21 | * SRV record payload (service pointer). 22 | */ 23 | public class SRV extends RRWithTarget implements Comparable { 24 | 25 | /** 26 | * The priority of this service. Lower values mean higher priority. 27 | */ 28 | public final int priority; 29 | 30 | /** 31 | * The weight of this service. Services with the same priority should be 32 | * balanced based on weight. 33 | */ 34 | public final int weight; 35 | 36 | /** 37 | * The target port. 38 | */ 39 | public final int port; 40 | 41 | public static SRV parse(DataInputStream dis, byte[] data) 42 | throws IOException { 43 | int priority = dis.readUnsignedShort(); 44 | int weight = dis.readUnsignedShort(); 45 | int port = dis.readUnsignedShort(); 46 | DnsName target = DnsName.parse(dis, data); 47 | return new SRV(priority, weight, port, target); 48 | } 49 | 50 | public SRV(int priority, int weight, int port, String target) { 51 | this(priority, weight, port, DnsName.from(target)); 52 | } 53 | 54 | public SRV(int priority, int weight, int port, DnsName target) { 55 | super(target); 56 | this.priority = priority; 57 | this.weight = weight; 58 | this.port = port; 59 | } 60 | 61 | /** 62 | * Check if the service is available at this domain. This checks f the target points to the root label. As per RFC 63 | * 2782 the service is decidedly not available if there is only a single SRV answer pointing to the root label. From 64 | * RFC 2782: 65 | * 66 | *
A Target of "." means that the service is decidedly not available at this domain.
67 | * 68 | * @return true if the service is available at this domain. 69 | */ 70 | public boolean isServiceAvailable() { 71 | return !target.isRootLabel(); 72 | } 73 | 74 | @Override 75 | public void serialize(DataOutputStream dos) throws IOException { 76 | dos.writeShort(priority); 77 | dos.writeShort(weight); 78 | dos.writeShort(port); 79 | super.serialize(dos); 80 | } 81 | 82 | @Override 83 | public String toString() { 84 | return priority + " " + weight + " " + port + " " + target + "."; 85 | } 86 | 87 | @Override 88 | public TYPE getType() { 89 | return TYPE.SRV; 90 | } 91 | 92 | @Override 93 | public int compareTo(SRV other) { 94 | int res = other.priority - this.priority; 95 | if (res == 0) { 96 | res = this.weight - other.weight; 97 | } 98 | return res; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/record/UNKNOWN.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import java.io.DataInputStream; 14 | import java.io.DataOutputStream; 15 | import java.io.IOException; 16 | 17 | import org.minidns.record.Record.TYPE; 18 | 19 | public final class UNKNOWN extends Data { 20 | 21 | private final TYPE type; 22 | private final byte[] data; 23 | 24 | private UNKNOWN(DataInputStream dis, int payloadLength, TYPE type) throws IOException { 25 | this.type = type; 26 | this.data = new byte[payloadLength]; 27 | dis.readFully(data); 28 | } 29 | 30 | @Override 31 | public TYPE getType() { 32 | return type; 33 | } 34 | 35 | @Override 36 | public void serialize(DataOutputStream dos) throws IOException { 37 | dos.write(data); 38 | } 39 | 40 | public static UNKNOWN parse(DataInputStream dis, int payloadLength, TYPE type) 41 | throws IOException { 42 | return new UNKNOWN(dis, payloadLength, type); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/util/Base32.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.util; 12 | 13 | /** 14 | * Very minimal Base32 encoder. 15 | */ 16 | public final class Base32 { 17 | private static final String ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; 18 | private static final String PADDING = "======"; 19 | 20 | /** 21 | * Do not allow to instantiate Base32 22 | */ 23 | private Base32() { 24 | } 25 | 26 | public static String encodeToString(byte[] bytes) { 27 | int paddingCount = (int) (8 - (bytes.length % 5) * 1.6) % 8; 28 | byte[] padded = new byte[bytes.length + paddingCount]; 29 | System.arraycopy(bytes, 0, padded, 0, bytes.length); 30 | StringBuilder sb = new StringBuilder(); 31 | for (int i = 0; i < bytes.length; i += 5) { 32 | long j = ((long) (padded[i] & 0xff) << 32) + ((long) (padded[i + 1] & 0xff) << 24) 33 | + ((padded[i + 2] & 0xff) << 16) + ((padded[i + 3] & 0xff) << 8) + (padded[i + 4] & 0xff); 34 | sb.append(ALPHABET.charAt((int) ((j >> 35) & 0x1f))).append(ALPHABET.charAt((int) ((j >> 30) & 0x1f))) 35 | .append(ALPHABET.charAt((int) ((j >> 25) & 0x1f))).append(ALPHABET.charAt((int) ((j >> 20) & 0x1f))) 36 | .append(ALPHABET.charAt((int) ((j >> 15) & 0x1f))).append(ALPHABET.charAt((int) ((j >> 10) & 0x1f))) 37 | .append(ALPHABET.charAt((int) ((j >> 5) & 0x1f))).append(ALPHABET.charAt((int) (j & 0x1f))); 38 | } 39 | return sb.substring(0, sb.length() - paddingCount) + PADDING.substring(0, paddingCount); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/util/Base64.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.util; 12 | 13 | /** 14 | * Very minimal Base64 encoder. 15 | */ 16 | public final class Base64 { 17 | private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 18 | private static final String PADDING = "=="; 19 | 20 | /** 21 | * Do not allow to instantiate Base64 22 | */ 23 | private Base64() { 24 | } 25 | 26 | public static String encodeToString(byte[] bytes) { 27 | int paddingCount = (3 - (bytes.length % 3)) % 3; 28 | byte[] padded = new byte[bytes.length + paddingCount]; 29 | System.arraycopy(bytes, 0, padded, 0, bytes.length); 30 | StringBuilder sb = new StringBuilder(); 31 | for (int i = 0; i < bytes.length; i += 3) { 32 | int j = ((padded[i] & 0xff) << 16) + ((padded[i + 1] & 0xff) << 8) + (padded[i + 2] & 0xff); 33 | sb.append(ALPHABET.charAt((j >> 18) & 0x3f)).append(ALPHABET.charAt((j >> 12) & 0x3f)) 34 | .append(ALPHABET.charAt((j >> 6) & 0x3f)).append(ALPHABET.charAt(j & 0x3f)); 35 | } 36 | return sb.substring(0, sb.length() - paddingCount) + PADDING.substring(0, paddingCount); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/util/CallbackRecipient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.util; 12 | 13 | /** 14 | * A recipient of success and exception callbacks. 15 | * 16 | * @param the type of the success value. 17 | * @param the type of the exception. 18 | */ 19 | public interface CallbackRecipient { 20 | 21 | CallbackRecipient onSuccess(SuccessCallback successCallback); 22 | 23 | CallbackRecipient onError(ExceptionCallback exceptionCallback); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/util/CollectionsUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.util; 12 | 13 | import java.util.Iterator; 14 | import java.util.Random; 15 | import java.util.Set; 16 | 17 | public class CollectionsUtil { 18 | 19 | public static T getRandomFrom(Set set, Random random) { 20 | int randomIndex = random.nextInt(set.size()); 21 | Iterator iterator = set.iterator(); 22 | for (int i = 0; i < randomIndex; i++) { 23 | if (!iterator.hasNext()) break; 24 | iterator.next(); 25 | } 26 | return iterator.next(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/util/ExceptionCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.util; 12 | 13 | public interface ExceptionCallback { 14 | 15 | void processException(E exception); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/util/Hex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.util; 12 | 13 | public class Hex { 14 | 15 | public static StringBuilder from(byte[] bytes) { 16 | StringBuilder sb = new StringBuilder(bytes.length * 2); 17 | for (byte b : bytes) { 18 | sb.append(String.format("%02X ", b)); 19 | } 20 | return sb; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/util/MultipleIoException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.util; 12 | 13 | import java.io.IOException; 14 | import java.util.Collection; 15 | import java.util.Collections; 16 | import java.util.Iterator; 17 | import java.util.List; 18 | 19 | public final class MultipleIoException extends IOException { 20 | 21 | /** 22 | * 23 | */ 24 | private static final long serialVersionUID = -5932211337552319515L; 25 | 26 | private final List ioExceptions; 27 | 28 | private MultipleIoException(List ioExceptions) { 29 | super(getMessage(ioExceptions)); 30 | assert !ioExceptions.isEmpty(); 31 | this.ioExceptions = Collections.unmodifiableList(ioExceptions); 32 | } 33 | 34 | public List getExceptions() { 35 | return ioExceptions; 36 | } 37 | 38 | private static String getMessage(Collection exceptions) { 39 | StringBuilder sb = new StringBuilder(); 40 | Iterator it = exceptions.iterator(); 41 | while (it.hasNext()) { 42 | sb.append(it.next().getMessage()); 43 | if (it.hasNext()) { 44 | sb.append(", "); 45 | } 46 | } 47 | return sb.toString(); 48 | } 49 | 50 | public static void throwIfRequired(List ioExceptions) throws IOException { 51 | if (ioExceptions == null || ioExceptions.isEmpty()) { 52 | return; 53 | } 54 | if (ioExceptions.size() == 1) { 55 | throw ioExceptions.get(0); 56 | } 57 | throw new MultipleIoException(ioExceptions); 58 | } 59 | 60 | public static IOException toIOException(List ioExceptions) { 61 | int size = ioExceptions.size(); 62 | if (size == 1) { 63 | return ioExceptions.get(0); 64 | } else if (size > 1) { 65 | return new MultipleIoException(ioExceptions); 66 | } 67 | return null; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/util/NameUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.util; 12 | 13 | import org.minidns.dnsname.DnsName; 14 | 15 | /** 16 | * Utilities related to internationalized domain names and dns name handling. 17 | */ 18 | public final class NameUtil { 19 | 20 | /** 21 | * Check if two internationalized domain names are equal, possibly causing 22 | * a serialization of both domain names. 23 | * 24 | * @param name1 The first domain name. 25 | * @param name2 The second domain name. 26 | * @return True if both domain names are the same. 27 | */ 28 | @SuppressWarnings("ReferenceEquality") 29 | public static boolean idnEquals(String name1, String name2) { 30 | if (name1 == name2) return true; // catches null, null 31 | if (name1 == null) return false; 32 | if (name2 == null) return false; 33 | if (name1.equals(name2)) return true; 34 | 35 | return DnsName.from(name1).compareTo(DnsName.from(name2)) == 0; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/util/PlatformDetection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.util; 12 | 13 | public class PlatformDetection { 14 | 15 | private static Boolean android; 16 | 17 | public static boolean isAndroid() { 18 | if (android == null) { 19 | try { 20 | Class.forName("android.Manifest"); // throws execption when not on Android 21 | android = true; 22 | } catch (Exception e) { 23 | android = false; 24 | } 25 | } 26 | return android; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/util/SafeCharSequence.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.util; 12 | 13 | public class SafeCharSequence implements CharSequence { 14 | 15 | @Override 16 | public final int length() { 17 | return toSafeString().length(); 18 | } 19 | 20 | @Override 21 | public final char charAt(int index) { 22 | return toSafeString().charAt(index); 23 | } 24 | 25 | @Override 26 | public final CharSequence subSequence(int start, int end) { 27 | return toSafeString().subSequence(end, end); 28 | } 29 | 30 | public String toSafeString() { 31 | // The default implementation assumes that toString() returns a safe 32 | // representation. Subclasses may override toSafeString() if this assumption is 33 | // not correct. 34 | return toString(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /minidns-core/src/main/java/org/minidns/util/SuccessCallback.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.util; 12 | 13 | public interface SuccessCallback { 14 | 15 | void onSuccess(T result); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /minidns-core/src/test/java/org/minidns/Assert.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertEquals; 14 | import static org.junit.jupiter.api.Assertions.assertTrue; 15 | 16 | import java.util.ArrayList; 17 | import java.util.Arrays; 18 | import java.util.Collection; 19 | import java.util.List; 20 | 21 | public class Assert { 22 | 23 | public static void assertCsEquals(CharSequence expected, CharSequence actual) { 24 | assertCsEquals(null, expected, actual); 25 | } 26 | 27 | public static void assertCsEquals(String message, CharSequence expected, CharSequence actual) { 28 | if (expected != null && actual != null) { 29 | assertEquals(expected.toString(), actual.toString(), message); 30 | } else { 31 | assertEquals(expected, actual, message); 32 | } 33 | } 34 | 35 | public static void assertArrayContentEquals(T[] expect, Collection value) { 36 | assertEquals(expect.length, value.size()); 37 | List list = new ArrayList<>(Arrays.asList(expect)); 38 | for (Object type : value) { 39 | assertTrue(list.remove(type)); 40 | } 41 | assertTrue(list.isEmpty()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /minidns-core/src/test/java/org/minidns/record/TLSATest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.record; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertEquals; 14 | import static org.junit.jupiter.api.Assertions.assertNotNull; 15 | 16 | import org.junit.jupiter.api.Test; 17 | 18 | public class TLSATest { 19 | 20 | @Test 21 | public void ensureTlsaLutsAreInitialized() { 22 | TLSA tlsa = new TLSA((byte) 3, (byte) 1, (byte) 2, new byte[] { 0x13, 0x37 }); 23 | 24 | assertEquals(3, tlsa.certUsageByte); 25 | assertNotNull(tlsa.certUsage); 26 | 27 | assertEquals(1, tlsa.selectorByte); 28 | assertNotNull(tlsa.selector); 29 | 30 | assertEquals(2, tlsa.matchingTypeByte); 31 | assertNotNull(tlsa.matchingType); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /minidns-core/src/test/java/org/minidns/util/Base32Test.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.util; 12 | 13 | import org.junit.jupiter.api.Test; 14 | 15 | import static org.junit.jupiter.api.Assertions.assertEquals; 16 | 17 | public class Base32Test { 18 | @Test 19 | public void testEncodeToString() { 20 | assertEquals("", Base32.encodeToString(new byte[] {})); 21 | assertEquals("0410====", Base32.encodeToString(new byte[] {1, 2})); 22 | assertEquals("891K8HA6", Base32.encodeToString(new byte[] {0x42, 0x43, 0x44, 0x45, 0x46})); 23 | assertEquals("VS0FU07V03VG0===", Base32.encodeToString(new byte[] {-1, 0, -1, 0, -1, 0, -1, 0})); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /minidns-core/src/test/java/org/minidns/util/Base64Test.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.util; 12 | 13 | import org.junit.jupiter.api.Test; 14 | 15 | import static org.junit.jupiter.api.Assertions.assertEquals; 16 | 17 | public class Base64Test { 18 | @Test 19 | public void testEncodeToString() { 20 | assertEquals("", Base64.encodeToString(new byte[] {})); 21 | assertEquals("Qg==", Base64.encodeToString(new byte[] {0x42})); 22 | assertEquals("AQID", Base64.encodeToString(new byte[] {1, 2, 3})); 23 | assertEquals("CAIGAP8B/wA=", Base64.encodeToString(new byte[] {8, 2, 6, 0, -1, 1, -1, 0})); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /minidns-core/src/test/java/org/minidns/util/NameUtilTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.util; 12 | 13 | import org.junit.jupiter.api.Test; 14 | 15 | import static org.junit.jupiter.api.Assertions.assertFalse; 16 | import static org.junit.jupiter.api.Assertions.assertTrue; 17 | 18 | public class NameUtilTest { 19 | 20 | @Test 21 | public void idnEqualsTest() { 22 | assertTrue(NameUtil.idnEquals(null, null)); 23 | assertTrue(NameUtil.idnEquals("domain.example", "domain.example")); 24 | assertTrue(NameUtil.idnEquals("dömäin.example", "xn--dmin-moa0i.example")); 25 | assertTrue(NameUtil.idnEquals("موقع.وزارة-الاتصالات.مصر", "xn--4gbrim.xn----ymcbaaajlc6dj7bxne2c.xn--wgbh1c")); 26 | 27 | assertFalse(NameUtil.idnEquals("dömäin.example", null)); 28 | assertFalse(NameUtil.idnEquals(null, "domain.example")); 29 | assertFalse(NameUtil.idnEquals("dömäin.example", "domain.example")); 30 | assertFalse(NameUtil.idnEquals("", "domain.example")); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /minidns-core/src/test/resources/org/minidns/dnsmessage/codinghorror-txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-core/src/test/resources/org/minidns/dnsmessage/codinghorror-txt -------------------------------------------------------------------------------- /minidns-core/src/test/resources/org/minidns/dnsmessage/com-ds-rrsig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-core/src/test/resources/org/minidns/dnsmessage/com-ds-rrsig -------------------------------------------------------------------------------- /minidns-core/src/test/resources/org/minidns/dnsmessage/com-ns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-core/src/test/resources/org/minidns/dnsmessage/com-ns -------------------------------------------------------------------------------- /minidns-core/src/test/resources/org/minidns/dnsmessage/com-nsec3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-core/src/test/resources/org/minidns/dnsmessage/com-nsec3 -------------------------------------------------------------------------------- /minidns-core/src/test/resources/org/minidns/dnsmessage/example-nsec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-core/src/test/resources/org/minidns/dnsmessage/example-nsec -------------------------------------------------------------------------------- /minidns-core/src/test/resources/org/minidns/dnsmessage/gmail-domainkey-txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-core/src/test/resources/org/minidns/dnsmessage/gmail-domainkey-txt -------------------------------------------------------------------------------- /minidns-core/src/test/resources/org/minidns/dnsmessage/gmail-mx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-core/src/test/resources/org/minidns/dnsmessage/gmail-mx -------------------------------------------------------------------------------- /minidns-core/src/test/resources/org/minidns/dnsmessage/google-aaaa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-core/src/test/resources/org/minidns/dnsmessage/google-aaaa -------------------------------------------------------------------------------- /minidns-core/src/test/resources/org/minidns/dnsmessage/gpn-srv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-core/src/test/resources/org/minidns/dnsmessage/gpn-srv -------------------------------------------------------------------------------- /minidns-core/src/test/resources/org/minidns/dnsmessage/oracle-soa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-core/src/test/resources/org/minidns/dnsmessage/oracle-soa -------------------------------------------------------------------------------- /minidns-core/src/test/resources/org/minidns/dnsmessage/root-dnskey: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-core/src/test/resources/org/minidns/dnsmessage/root-dnskey -------------------------------------------------------------------------------- /minidns-core/src/test/resources/org/minidns/dnsmessage/sun-a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-core/src/test/resources/org/minidns/dnsmessage/sun-a -------------------------------------------------------------------------------- /minidns-dane/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.minidns.java-conventions' 3 | } 4 | 5 | description = "Support for DANE using APIs of Java 7 (or higher)" 6 | 7 | dependencies { 8 | api project(':minidns-dnssec') 9 | testImplementation project(path: ":minidns-client", configuration: "testRuntime") 10 | testImplementation project(path: ":minidns-dnssec", configuration: "testRuntime") 11 | } 12 | -------------------------------------------------------------------------------- /minidns-dane/src/test/java/org/minidns/dane/java7/DaneJava7Test.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dane.java7; 12 | 13 | import org.junit.jupiter.api.Test; 14 | 15 | public class DaneJava7Test { 16 | /** 17 | * Just here to ensure jacoco is not complaining. 18 | */ 19 | @Test 20 | public void emptyTest() { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /minidns-dnssec/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.minidns.java-conventions' 3 | id 'org.minidns.android-conventions' 4 | } 5 | 6 | description = "MiniDNS' client with support for DNSSEC" 7 | 8 | dependencies { 9 | api project(':minidns-client') 10 | api project(':minidns-iterative-resolver') 11 | testImplementation project(path: ":minidns-client", configuration: "testRuntime") 12 | } 13 | -------------------------------------------------------------------------------- /minidns-dnssec/src/main/java/org/minidns/dane/DaneCertificateException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dane; 12 | 13 | import java.security.cert.CertificateException; 14 | import java.util.Collections; 15 | import java.util.List; 16 | 17 | import org.minidns.record.TLSA; 18 | 19 | public abstract class DaneCertificateException extends CertificateException { 20 | 21 | /** 22 | * 23 | */ 24 | private static final long serialVersionUID = 1L; 25 | 26 | protected DaneCertificateException() { 27 | } 28 | 29 | protected DaneCertificateException(String message) { 30 | super(message); 31 | } 32 | 33 | public static class CertificateMismatch extends DaneCertificateException { 34 | 35 | /** 36 | * 37 | */ 38 | private static final long serialVersionUID = 1L; 39 | 40 | public final TLSA tlsa; 41 | public final byte[] computed; 42 | 43 | public CertificateMismatch(TLSA tlsa, byte[] computed) { 44 | super("The TLSA RR does not match the certificate"); 45 | this.tlsa = tlsa; 46 | this.computed = computed; 47 | } 48 | } 49 | 50 | public static class MultipleCertificateMismatchExceptions extends DaneCertificateException { 51 | 52 | /** 53 | * 54 | */ 55 | private static final long serialVersionUID = 1L; 56 | 57 | public final List certificateMismatchExceptions; 58 | 59 | public MultipleCertificateMismatchExceptions(List certificateMismatchExceptions) { 60 | super("There where multiple CertificateMismatch exceptions because none of the TLSA RR does match the certificate"); 61 | assert !certificateMismatchExceptions.isEmpty(); 62 | this.certificateMismatchExceptions = Collections.unmodifiableList(certificateMismatchExceptions); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /minidns-dnssec/src/main/java/org/minidns/dane/ExpectingTrustManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dane; 12 | 13 | import javax.net.ssl.X509TrustManager; 14 | import java.security.cert.CertificateException; 15 | import java.security.cert.X509Certificate; 16 | 17 | public class ExpectingTrustManager implements X509TrustManager { 18 | private CertificateException exception; 19 | private final X509TrustManager trustManager; 20 | 21 | /** 22 | * Creates a new instance of ExpectingTrustManager. 23 | * 24 | * @param trustManager The {@link X509TrustManager} to be used for verification. 25 | * {@code null} to use the system default. 26 | */ 27 | public ExpectingTrustManager(X509TrustManager trustManager) { 28 | this.trustManager = trustManager == null ? X509TrustManagerUtil.getDefault() : trustManager; 29 | } 30 | 31 | public boolean hasException() { 32 | return exception != null; 33 | } 34 | 35 | public CertificateException getException() { 36 | CertificateException e = exception; 37 | exception = null; 38 | return e; 39 | } 40 | 41 | @Override 42 | public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 43 | try { 44 | trustManager.checkClientTrusted(chain, authType); 45 | } catch (CertificateException e) { 46 | exception = e; 47 | } 48 | } 49 | 50 | @Override 51 | public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 52 | try { 53 | trustManager.checkServerTrusted(chain, authType); 54 | } catch (CertificateException e) { 55 | exception = e; 56 | } 57 | } 58 | 59 | @Override 60 | public X509Certificate[] getAcceptedIssuers() { 61 | return trustManager.getAcceptedIssuers(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /minidns-dnssec/src/main/java/org/minidns/dane/X509TrustManagerUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dane; 12 | 13 | import java.security.KeyStore; 14 | import java.security.KeyStoreException; 15 | import java.security.NoSuchAlgorithmException; 16 | 17 | import javax.net.ssl.TrustManager; 18 | import javax.net.ssl.TrustManagerFactory; 19 | import javax.net.ssl.X509TrustManager; 20 | 21 | public class X509TrustManagerUtil { 22 | 23 | public static X509TrustManager getDefault() { 24 | return getDefault(null); 25 | } 26 | 27 | public static X509TrustManager getDefault(KeyStore keyStore) { 28 | String defaultAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 29 | TrustManagerFactory trustManagerFactory; 30 | try { 31 | trustManagerFactory = TrustManagerFactory.getInstance(defaultAlgorithm); 32 | trustManagerFactory.init(keyStore); 33 | } catch (NoSuchAlgorithmException | KeyStoreException e) { 34 | throw new AssertionError(e); 35 | } 36 | 37 | for (TrustManager trustManager : trustManagerFactory.getTrustManagers()) { 38 | if (trustManager instanceof X509TrustManager) { 39 | return (X509TrustManager) trustManager; 40 | } 41 | } 42 | throw new AssertionError("No trust manager for the default algorithm " + defaultAlgorithm + " found"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /minidns-dnssec/src/main/java/org/minidns/dnssec/DigestCalculator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnssec; 12 | 13 | public interface DigestCalculator { 14 | byte[] digest(byte[] bytes); 15 | } 16 | -------------------------------------------------------------------------------- /minidns-dnssec/src/main/java/org/minidns/dnssec/DnssecQueryResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnssec; 12 | 13 | import java.util.Collections; 14 | import java.util.Set; 15 | 16 | import org.minidns.dnsmessage.DnsMessage; 17 | import org.minidns.dnsqueryresult.DnsQueryResult; 18 | import org.minidns.record.RRSIG; 19 | import org.minidns.record.Record; 20 | 21 | public class DnssecQueryResult { 22 | 23 | public final DnsMessage synthesizedResponse; 24 | public final DnsQueryResult dnsQueryResult; 25 | 26 | private final Set> signatures; 27 | private final Set dnssecUnverifiedReasons; 28 | 29 | DnssecQueryResult(DnsMessage synthesizedResponse, DnsQueryResult dnsQueryResult, Set> signatures, 30 | Set dnssecUnverifiedReasons) { 31 | this.synthesizedResponse = synthesizedResponse; 32 | this.dnsQueryResult = dnsQueryResult; 33 | this.signatures = Collections.unmodifiableSet(signatures); 34 | if (dnssecUnverifiedReasons == null) { 35 | this.dnssecUnverifiedReasons = Collections.emptySet(); 36 | } else { 37 | this.dnssecUnverifiedReasons = Collections.unmodifiableSet(dnssecUnverifiedReasons); 38 | } 39 | } 40 | 41 | public boolean isAuthenticData() { 42 | return dnssecUnverifiedReasons.isEmpty(); 43 | } 44 | 45 | public Set> getSignatures() { 46 | return signatures; 47 | } 48 | 49 | public Set getUnverifiedReasons() { 50 | return dnssecUnverifiedReasons; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /minidns-dnssec/src/main/java/org/minidns/dnssec/DnssecResultNotAuthenticException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnssec; 12 | 13 | import java.util.Collections; 14 | import java.util.Set; 15 | 16 | import org.minidns.MiniDnsException; 17 | 18 | public final class DnssecResultNotAuthenticException extends MiniDnsException { 19 | 20 | /** 21 | * 22 | */ 23 | private static final long serialVersionUID = 1L; 24 | 25 | private final Set unverifiedReasons; 26 | 27 | private DnssecResultNotAuthenticException(String message, Set unverifiedReasons) { 28 | super(message); 29 | if (unverifiedReasons.isEmpty()) { 30 | throw new IllegalArgumentException(); 31 | } 32 | this.unverifiedReasons = Collections.unmodifiableSet(unverifiedReasons); 33 | } 34 | 35 | public static DnssecResultNotAuthenticException from(Set unverifiedReasons) { 36 | StringBuilder sb = new StringBuilder(); 37 | sb.append("DNSSEC result not authentic. Reasons: "); 38 | for (DnssecUnverifiedReason reason : unverifiedReasons) { 39 | sb.append(reason).append('.'); 40 | } 41 | 42 | return new DnssecResultNotAuthenticException(sb.toString(), unverifiedReasons); 43 | } 44 | 45 | public Set getUnverifiedReasons() { 46 | return unverifiedReasons; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /minidns-dnssec/src/main/java/org/minidns/dnssec/DnssecValidatorInitializationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnssec; 12 | 13 | public class DnssecValidatorInitializationException extends RuntimeException { 14 | private static final long serialVersionUID = -1464257268053507791L; 15 | 16 | public DnssecValidatorInitializationException(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /minidns-dnssec/src/main/java/org/minidns/dnssec/SignatureVerifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnssec; 12 | 13 | import org.minidns.record.DNSKEY; 14 | import org.minidns.record.RRSIG; 15 | 16 | public interface SignatureVerifier { 17 | boolean verify(byte[] content, RRSIG rrsig, DNSKEY key) throws DnssecValidationFailedException; 18 | } 19 | -------------------------------------------------------------------------------- /minidns-dnssec/src/main/java/org/minidns/dnssec/algorithms/EcgostSignatureVerifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnssec.algorithms; 12 | 13 | import org.minidns.dnssec.DnssecValidationFailedException.DnssecInvalidKeySpecException; 14 | import org.minidns.record.DNSKEY; 15 | import org.minidns.record.RRSIG; 16 | import org.minidns.dnssec.DnssecValidationFailedException.DataMalformedException; 17 | 18 | import java.io.DataInput; 19 | import java.io.IOException; 20 | import java.math.BigInteger; 21 | import java.security.NoSuchAlgorithmException; 22 | import java.security.PublicKey; 23 | import java.security.spec.ECFieldFp; 24 | import java.security.spec.ECParameterSpec; 25 | import java.security.spec.ECPoint; 26 | import java.security.spec.ECPublicKeySpec; 27 | import java.security.spec.EllipticCurve; 28 | import java.security.spec.InvalidKeySpecException; 29 | 30 | class EcgostSignatureVerifier extends JavaSecSignatureVerifier { 31 | private static final int LENGTH = 32; 32 | private static final ECParameterSpec SPEC = new ECParameterSpec( 33 | new EllipticCurve( 34 | new ECFieldFp(new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", 16)), 35 | new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94", 16), 36 | new BigInteger("A6", 16) 37 | ), 38 | new ECPoint(BigInteger.ONE, new BigInteger("8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14", 16)), 39 | new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893", 16), 40 | 1 41 | ); 42 | 43 | EcgostSignatureVerifier() throws NoSuchAlgorithmException { 44 | super("ECGOST3410", "GOST3411withECGOST3410"); 45 | } 46 | 47 | @Override 48 | protected byte[] getSignature(RRSIG rrsig) { 49 | return rrsig.getSignature(); 50 | } 51 | 52 | @Override 53 | protected PublicKey getPublicKey(DNSKEY key) throws DataMalformedException, DnssecInvalidKeySpecException { 54 | DataInput dis = key.getKeyAsDataInputStream(); 55 | BigInteger x, y; 56 | 57 | try { 58 | byte[] xBytes = new byte[LENGTH]; 59 | dis.readFully(xBytes); 60 | reverse(xBytes); 61 | x = new BigInteger(1, xBytes); 62 | 63 | byte[] yBytes = new byte[LENGTH]; 64 | dis.readFully(yBytes); 65 | reverse(yBytes); 66 | y = new BigInteger(1, yBytes); 67 | } catch (IOException e) { 68 | throw new DataMalformedException(e, key.getKey()); 69 | } 70 | 71 | try { 72 | return getKeyFactory().generatePublic(new ECPublicKeySpec(new ECPoint(x, y), SPEC)); 73 | } catch (InvalidKeySpecException e) { 74 | throw new DnssecInvalidKeySpecException(e); 75 | } 76 | } 77 | 78 | private static void reverse(byte[] array) { 79 | for (int i = 0; i < array.length / 2; i++) { 80 | int j = array.length - i - 1; 81 | byte tmp = array[i]; 82 | array[i] = array[j]; 83 | array[j] = tmp; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /minidns-dnssec/src/main/java/org/minidns/dnssec/algorithms/JavaSecDigestCalculator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnssec.algorithms; 12 | 13 | import org.minidns.dnssec.DigestCalculator; 14 | 15 | import java.security.MessageDigest; 16 | import java.security.NoSuchAlgorithmException; 17 | 18 | public class JavaSecDigestCalculator implements DigestCalculator { 19 | private MessageDigest md; 20 | 21 | public JavaSecDigestCalculator(String algorithm) throws NoSuchAlgorithmException { 22 | md = MessageDigest.getInstance(algorithm); 23 | } 24 | 25 | @Override 26 | public byte[] digest(byte[] bytes) { 27 | return md.digest(bytes); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /minidns-dnssec/src/main/java/org/minidns/dnssec/algorithms/JavaSecSignatureVerifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnssec.algorithms; 12 | 13 | import org.minidns.dnssec.DnssecValidationFailedException; 14 | import org.minidns.dnssec.DnssecValidationFailedException.DataMalformedException; 15 | import org.minidns.dnssec.DnssecValidationFailedException.DnssecInvalidKeySpecException; 16 | import org.minidns.dnssec.SignatureVerifier; 17 | import org.minidns.record.DNSKEY; 18 | import org.minidns.record.RRSIG; 19 | 20 | import java.security.InvalidKeyException; 21 | import java.security.KeyFactory; 22 | import java.security.NoSuchAlgorithmException; 23 | import java.security.PublicKey; 24 | import java.security.Signature; 25 | import java.security.SignatureException; 26 | 27 | public abstract class JavaSecSignatureVerifier implements SignatureVerifier { 28 | private final KeyFactory keyFactory; 29 | private final String signatureAlgorithm; 30 | 31 | public JavaSecSignatureVerifier(String keyAlgorithm, String signatureAlgorithm) throws NoSuchAlgorithmException { 32 | keyFactory = KeyFactory.getInstance(keyAlgorithm); 33 | this.signatureAlgorithm = signatureAlgorithm; 34 | 35 | // Verify signature algorithm to be valid 36 | Signature.getInstance(signatureAlgorithm); 37 | } 38 | 39 | public KeyFactory getKeyFactory() { 40 | return keyFactory; 41 | } 42 | 43 | @Override 44 | public boolean verify(byte[] content, RRSIG rrsig, DNSKEY key) throws DnssecValidationFailedException { 45 | try { 46 | PublicKey publicKey = getPublicKey(key); 47 | Signature signature = Signature.getInstance(signatureAlgorithm); 48 | signature.initVerify(publicKey); 49 | signature.update(content); 50 | return signature.verify(getSignature(rrsig)); 51 | } catch (NoSuchAlgorithmException e) { 52 | // We checked against this before, it should never happen! 53 | throw new AssertionError(e); 54 | } catch (InvalidKeyException | SignatureException | ArithmeticException e) { 55 | throw new DnssecValidationFailedException("Validating signature failed", e); 56 | } 57 | } 58 | 59 | protected abstract byte[] getSignature(RRSIG rrsig) throws DataMalformedException; 60 | 61 | protected abstract PublicKey getPublicKey(DNSKEY key) throws DataMalformedException, DnssecInvalidKeySpecException; 62 | } 63 | -------------------------------------------------------------------------------- /minidns-dnssec/src/main/java/org/minidns/dnssec/algorithms/RsaSignatureVerifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnssec.algorithms; 12 | 13 | import org.minidns.dnssec.DnssecValidationFailedException.DnssecInvalidKeySpecException; 14 | import org.minidns.record.DNSKEY; 15 | import org.minidns.record.RRSIG; 16 | import org.minidns.dnssec.DnssecValidationFailedException.DataMalformedException; 17 | 18 | import java.io.DataInput; 19 | import java.io.IOException; 20 | import java.math.BigInteger; 21 | import java.security.NoSuchAlgorithmException; 22 | import java.security.PublicKey; 23 | import java.security.spec.InvalidKeySpecException; 24 | import java.security.spec.RSAPublicKeySpec; 25 | 26 | class RsaSignatureVerifier extends JavaSecSignatureVerifier { 27 | RsaSignatureVerifier(String algorithm) throws NoSuchAlgorithmException { 28 | super("RSA", algorithm); 29 | } 30 | 31 | @Override 32 | protected PublicKey getPublicKey(DNSKEY key) throws DataMalformedException, DnssecInvalidKeySpecException { 33 | DataInput dis = key.getKeyAsDataInputStream(); 34 | BigInteger exponent, modulus; 35 | 36 | try { 37 | int exponentLength = dis.readUnsignedByte(); 38 | int bytesRead = 1; 39 | if (exponentLength == 0) { 40 | bytesRead += 2; 41 | exponentLength = dis.readUnsignedShort(); 42 | } 43 | 44 | byte[] exponentBytes = new byte[exponentLength]; 45 | dis.readFully(exponentBytes); 46 | bytesRead += exponentLength; 47 | exponent = new BigInteger(1, exponentBytes); 48 | 49 | byte[] modulusBytes = new byte[key.getKeyLength() - bytesRead]; 50 | dis.readFully(modulusBytes); 51 | modulus = new BigInteger(1, modulusBytes); 52 | } catch (IOException e) { 53 | throw new DataMalformedException(e, key.getKey()); 54 | } 55 | 56 | try { 57 | return getKeyFactory().generatePublic(new RSAPublicKeySpec(modulus, exponent)); 58 | } catch (InvalidKeySpecException e) { 59 | throw new DnssecInvalidKeySpecException(e); 60 | } 61 | } 62 | 63 | @Override 64 | protected byte[] getSignature(RRSIG rrsig) { 65 | return rrsig.getSignature(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /minidns-dnssec/src/main/resources/.keep-minidns-dnssec-main-resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-dnssec/src/main/resources/.keep-minidns-dnssec-main-resources -------------------------------------------------------------------------------- /minidns-dnssec/src/test/java/org/minidns/dnssec/algorithms/AlgorithmTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnssec.algorithms; 12 | 13 | public class AlgorithmTest { 14 | protected static AlgorithmMap algorithmMap; 15 | 16 | static { 17 | algorithmMap = AlgorithmMap.INSTANCE; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /minidns-dnssec/src/test/java/org/minidns/dnssec/algorithms/DigestTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnssec.algorithms; 12 | 13 | import org.minidns.constants.DnssecConstants.DigestAlgorithm; 14 | import org.minidns.dnssec.DigestCalculator; 15 | import org.minidns.record.NSEC3.HashAlgorithm; 16 | 17 | import org.junit.jupiter.api.Test; 18 | 19 | import java.math.BigInteger; 20 | import java.nio.charset.StandardCharsets; 21 | 22 | import static org.junit.jupiter.api.Assertions.assertEquals; 23 | 24 | public class DigestTest extends AlgorithmTest { 25 | 26 | @Test 27 | public void testSha1DsDigest() { 28 | DigestCalculator dsDigestCalculator = algorithmMap.getDsDigestCalculator(DigestAlgorithm.SHA1); 29 | assertEquals("da39a3ee5e6b4b0d3255bfef95601890afd80709", digestHexString(dsDigestCalculator, "")); 30 | assertEquals("a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", digestHexString(dsDigestCalculator, "test")); 31 | assertEquals("640ab2bae07bedc4c163f679a746f7ab7fb5d1fa", digestHexString(dsDigestCalculator, "Test")); 32 | } 33 | 34 | @Test 35 | public void testSha256DsDigest() { 36 | DigestCalculator dsDigestCalculator = algorithmMap.getDsDigestCalculator(DigestAlgorithm.SHA256); 37 | assertEquals("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", digestHexString(dsDigestCalculator, "")); 38 | assertEquals("9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", digestHexString(dsDigestCalculator, "test")); 39 | assertEquals("532eaabd9574880dbf76b9b8cc00832c20a6ec113d682299550d7a6e0f345e25", digestHexString(dsDigestCalculator, "Test")); 40 | } 41 | 42 | @Test 43 | public void testSha1nsec3Digest() { 44 | DigestCalculator nsecDigestCalculator = algorithmMap.getNsecDigestCalculator(HashAlgorithm.SHA1); 45 | assertEquals("da39a3ee5e6b4b0d3255bfef95601890afd80709", digestHexString(nsecDigestCalculator, "")); 46 | assertEquals("a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", digestHexString(nsecDigestCalculator, "test")); 47 | assertEquals("640ab2bae07bedc4c163f679a746f7ab7fb5d1fa", digestHexString(nsecDigestCalculator, "Test")); 48 | } 49 | 50 | private static String digestHexString(DigestCalculator digestCalculator, String in) { 51 | return new BigInteger(1, digestCalculator.digest(in.getBytes(StandardCharsets.UTF_8))).toString(16); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /minidns-dnssec/src/test/java/org/minidns/dnssec/algorithms/DsaSingatureVerifierTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnssec.algorithms; 12 | 13 | import org.minidns.constants.DnssecConstants.SignatureAlgorithm; 14 | import org.minidns.dnssec.DnssecValidationFailedException; 15 | import org.minidns.dnssec.DnssecValidationFailedException.DataMalformedException; 16 | import org.junit.jupiter.api.Test; 17 | 18 | import static org.junit.jupiter.api.Assertions.assertThrows; 19 | import static org.minidns.dnssec.DnssecWorld.generatePrivateKey; 20 | import static org.minidns.dnssec.DnssecWorld.publicKey; 21 | import static org.minidns.dnssec.DnssecWorld.sign; 22 | 23 | public class DsaSingatureVerifierTest extends SignatureVerifierTest { 24 | private static final SignatureAlgorithm ALGORITHM = SignatureAlgorithm.DSA; 25 | 26 | @Test 27 | public void testDSA1024Valid() throws DnssecValidationFailedException { 28 | verifierTest(1024, ALGORITHM); 29 | } 30 | 31 | @Test 32 | public void testDSA512Valid() throws DnssecValidationFailedException { 33 | verifierTest(512, ALGORITHM); 34 | } 35 | 36 | @Test 37 | public void testDSAIllegalSignature() { 38 | byte[] sample = new byte[] { 0x0 }; 39 | assertThrows(DataMalformedException.class, () -> 40 | assertSignatureValid(publicKey(ALGORITHM, generatePrivateKey(ALGORITHM, 1024)), ALGORITHM, sample, sample) 41 | ); 42 | } 43 | 44 | @Test 45 | public void testDSAIllegalPublicKey() { 46 | byte[] sample = getRandomBytes(); 47 | 48 | assertThrows(DataMalformedException.class, () -> 49 | assertSignatureValid(new byte[] {0x0}, ALGORITHM, sign(generatePrivateKey(ALGORITHM, 1024), ALGORITHM, sample), sample) 50 | ); 51 | } 52 | 53 | @Test 54 | public void testDSAWrongSignature() throws DnssecValidationFailedException { 55 | byte[] sample = getRandomBytes(); 56 | assertSignatureInvalid(publicKey(ALGORITHM, generatePrivateKey(ALGORITHM, 1024)), ALGORITHM, 57 | sign(generatePrivateKey(ALGORITHM, 1024), ALGORITHM, sample), sample); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /minidns-dnssec/src/test/java/org/minidns/dnssec/algorithms/SignatureVerifierTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.dnssec.algorithms; 12 | 13 | import org.minidns.constants.DnssecConstants.SignatureAlgorithm; 14 | import org.minidns.dnsname.DnsName; 15 | import org.minidns.dnssec.DnssecValidationFailedException; 16 | import org.minidns.record.DNSKEY; 17 | import org.minidns.record.RRSIG; 18 | 19 | import java.security.PrivateKey; 20 | import java.util.concurrent.ThreadLocalRandom; 21 | 22 | import static org.minidns.dnssec.DnssecWorld.generatePrivateKey; 23 | import static org.minidns.dnssec.DnssecWorld.publicKey; 24 | import static org.minidns.dnssec.DnssecWorld.sign; 25 | import static org.junit.jupiter.api.Assertions.assertFalse; 26 | import static org.junit.jupiter.api.Assertions.assertTrue; 27 | 28 | public class SignatureVerifierTest extends AlgorithmTest { 29 | 30 | protected void verifierTest(int length, SignatureAlgorithm algorithm) throws DnssecValidationFailedException { 31 | verifierTest(generatePrivateKey(algorithm, length), algorithm); 32 | } 33 | 34 | protected void verifierTest(PrivateKey privateKey, SignatureAlgorithm algorithm) throws DnssecValidationFailedException { 35 | byte[] sample = getRandomBytes(); 36 | assertSignatureValid(publicKey(algorithm, privateKey), algorithm, sign(privateKey, algorithm, sample), sample); 37 | } 38 | 39 | protected static void assertSignatureValid(byte[] publicKey, SignatureAlgorithm algorithm, byte[] signature, 40 | byte[] signedBytes) throws DnssecValidationFailedException { 41 | assertTrue(verify(publicKey, algorithm, signature, signedBytes)); 42 | } 43 | 44 | protected static void assertSignatureInvalid(byte[] publicKey, SignatureAlgorithm algorithm, byte[] signature, 45 | byte[] signedBytes) throws DnssecValidationFailedException { 46 | assertFalse(verify(publicKey, algorithm, signature, signedBytes)); 47 | } 48 | 49 | private static boolean verify(byte[] publicKey, SignatureAlgorithm algorithm, byte[] signature, byte[] signedBytes) 50 | throws DnssecValidationFailedException { 51 | DNSKEY key = new DNSKEY((short) 0, (byte) 0, algorithm, publicKey); 52 | RRSIG rrsig = new RRSIG(null, algorithm, (byte) 0, (long) 0, null, null, 0, DnsName.ROOT, signature); 53 | 54 | boolean res = algorithmMap.getSignatureVerifier(algorithm).verify(signedBytes, rrsig, key); 55 | return res; 56 | } 57 | 58 | protected static byte[] getRandomBytes() { 59 | byte[] randomBytes = new byte[1024]; 60 | ThreadLocalRandom.current().nextBytes(randomBytes); 61 | return randomBytes; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /minidns-dnssec/src/test/resources/.keep-minidns-dnssec-test-resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MiniDNS/minidns/46a3e8c6c1078daab02905c4cbe016286132601e/minidns-dnssec/src/test/resources/.keep-minidns-dnssec-test-resources -------------------------------------------------------------------------------- /minidns-hla/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.minidns.java-conventions' 3 | id 'org.minidns.android-conventions' 4 | } 5 | 6 | description = "An easy to use high-level API (HLA) of MiniDNS' client" 7 | 8 | dependencies { 9 | api project(':minidns-dnssec') 10 | testImplementation project(path: ":minidns-client", configuration: "testRuntime") 11 | testImplementation project(path: ":minidns-dnssec", configuration: "testRuntime") 12 | } 13 | -------------------------------------------------------------------------------- /minidns-hla/src/main/java/org/minidns/hla/ResolutionUnsuccessfulException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.hla; 12 | 13 | import org.minidns.MiniDnsException; 14 | import org.minidns.dnsmessage.Question; 15 | import org.minidns.dnsmessage.DnsMessage.RESPONSE_CODE; 16 | 17 | public class ResolutionUnsuccessfulException extends MiniDnsException { 18 | 19 | /** 20 | * 21 | */ 22 | private static final long serialVersionUID = 1L; 23 | 24 | public final Question question; 25 | public final RESPONSE_CODE responseCode; 26 | 27 | public ResolutionUnsuccessfulException(Question question, RESPONSE_CODE responseCode) { 28 | super("Asking for " + question + " yielded an error response " + responseCode); 29 | this.question = question; 30 | this.responseCode = responseCode; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /minidns-hla/src/main/java/org/minidns/hla/srv/SrvProto.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.hla.srv; 12 | 13 | import org.minidns.dnslabel.DnsLabel; 14 | 15 | public enum SrvProto { 16 | 17 | // @formatter:off 18 | tcp, 19 | udp, 20 | ; 21 | // @formatter:on 22 | 23 | @SuppressWarnings("ImmutableEnumChecker") 24 | public final DnsLabel dnsLabel; 25 | 26 | SrvProto() { 27 | dnsLabel = DnsLabel.from('_' + name()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /minidns-hla/src/main/java/org/minidns/hla/srv/SrvService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.hla.srv; 12 | 13 | import org.minidns.dnslabel.DnsLabel; 14 | 15 | public enum SrvService { 16 | 17 | // @formatter:off 18 | xmpp_client, 19 | xmpp_server, 20 | 21 | /** 22 | * XMPP client-to-server (c2s) connections using implicit TLS (also known as "Direct TLS"). 23 | * 24 | * @see XEP-0368: SRV records for XMPP over TLS 25 | */ 26 | xmpps_client, 27 | 28 | /** 29 | * XMPP server-to-server (s2s) connections using implicit TLS (also known as "Direct TLS"). 30 | * 31 | * @see XEP-0368: SRV records for XMPP over TLS 32 | */ 33 | xmpps_server, 34 | ; 35 | // @formatter:on 36 | 37 | @SuppressWarnings("ImmutableEnumChecker") 38 | public final DnsLabel dnsLabel; 39 | 40 | SrvService() { 41 | String enumName = name().replaceAll("_", "-"); 42 | dnsLabel = DnsLabel.from('_' + enumName); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /minidns-hla/src/main/java/org/minidns/hla/srv/SrvServiceProto.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.hla.srv; 12 | 13 | import org.minidns.dnslabel.DnsLabel; 14 | 15 | /** 16 | * The Serivce and Protocol part of a SRV owner name. The format of a SRV owner name is "_Service._Proto.Name". 17 | */ 18 | public class SrvServiceProto { 19 | 20 | public final DnsLabel service; 21 | public final DnsLabel proto; 22 | 23 | public SrvServiceProto(DnsLabel service, DnsLabel proto) { 24 | this.service = service; 25 | this.proto = proto; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /minidns-hla/src/main/java/org/minidns/hla/srv/SrvType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.hla.srv; 12 | 13 | public enum SrvType { 14 | 15 | // @formatter:off 16 | xmpp_client(SrvService.xmpp_client, SrvProto.tcp), 17 | xmpp_server(SrvService.xmpp_server, SrvProto.tcp), 18 | ; 19 | // @formatter:on 20 | 21 | public final SrvService service; 22 | public final SrvProto proto; 23 | 24 | SrvType(SrvService service, SrvProto proto) { 25 | this.service = service; 26 | this.proto = proto; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /minidns-hla/src/test/java/org/minidns/hla/MiniDnsHlaTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.hla; 12 | 13 | import org.junit.jupiter.api.Test; 14 | 15 | public class MiniDnsHlaTest { 16 | 17 | /** 18 | * Dummy test to make jacocoRootReport happy. 19 | */ 20 | @Test 21 | public void nopTest() { 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /minidns-integration-test/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | plugins { 12 | id 'org.minidns.java-conventions' 13 | id 'org.minidns.application-conventions' 14 | } 15 | 16 | description = "MiniDNS' integration test suite" 17 | 18 | mainClassName = 'org.minidns.integrationtest.IntegrationTestHelper' 19 | applicationDefaultJvmArgs = ["-enableassertions"] 20 | 21 | dependencies { 22 | api project(':minidns-client') 23 | api project(':minidns-async') 24 | api project(':minidns-iterative-resolver') 25 | api project(':minidns-dnssec') 26 | api project(':minidns-hla') 27 | implementation "org.junit.vintage:junit-vintage-engine:$junitVersion" 28 | implementation "org.junit.jupiter:junit-jupiter-api:$junitVersion" 29 | testImplementation project(path: ":minidns-client", configuration: "testRuntime") 30 | } 31 | 32 | run { 33 | // Pass all system properties down to the "application" run. 34 | // Used e.g. for integration test configuration via properties. 35 | systemProperties System.getProperties() 36 | } 37 | -------------------------------------------------------------------------------- /minidns-integration-test/src/main/java/org/minidns/integrationtest/AsyncApiTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.integrationtest; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertEquals; 14 | 15 | import java.io.IOException; 16 | 17 | import org.minidns.DnsClient; 18 | import org.minidns.record.Record; 19 | import org.minidns.MiniDnsFuture; 20 | import org.minidns.dnsmessage.DnsMessage.RESPONSE_CODE; 21 | import org.minidns.dnsqueryresult.DnsQueryResult; 22 | import org.minidns.source.AbstractDnsDataSource; 23 | import org.minidns.source.AbstractDnsDataSource.QueryMode; 24 | import org.minidns.source.async.AsyncNetworkDataSource; 25 | 26 | public class AsyncApiTest { 27 | 28 | public static void main(String[] args) throws IOException { 29 | tcpAsyncApiTest(); 30 | } 31 | 32 | public static void simpleAsyncApiTest() throws IOException { 33 | DnsClient client = new DnsClient(); 34 | client.setDataSource(new AsyncNetworkDataSource()); 35 | client.getDataSource().setTimeout(60 * 60 * 1000); 36 | 37 | MiniDnsFuture future = client.queryAsync("example.com", Record.TYPE.NS); 38 | DnsQueryResult result = future.getOrThrow(); 39 | assertEquals(RESPONSE_CODE.NO_ERROR, result.response.responseCode); 40 | } 41 | 42 | public static void tcpAsyncApiTest() throws IOException { 43 | AbstractDnsDataSource dataSource = new AsyncNetworkDataSource(); 44 | dataSource.setTimeout(60 * 60 * 1000); 45 | dataSource.setUdpPayloadSize(256); 46 | dataSource.setQueryMode(QueryMode.tcp); 47 | 48 | DnsClient client = new DnsClient(); 49 | client.setDataSource(dataSource); 50 | client.setAskForDnssec(true); 51 | 52 | MiniDnsFuture future = client.queryAsync("google.com", Record.TYPE.AAAA); 53 | DnsQueryResult result = future.getOrThrow(); 54 | assertEquals(RESPONSE_CODE.NO_ERROR, result.response.responseCode); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /minidns-integration-test/src/main/java/org/minidns/integrationtest/CoreTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.integrationtest; 12 | 13 | import org.minidns.DnsClient; 14 | import org.minidns.cache.LruCache; 15 | import org.minidns.dnsqueryresult.DnsQueryResult; 16 | import org.minidns.record.Data; 17 | import org.minidns.record.Record; 18 | 19 | import java.io.IOException; 20 | import java.util.ArrayList; 21 | import java.util.Collections; 22 | import java.util.List; 23 | 24 | import static org.junit.jupiter.api.Assertions.assertEquals; 25 | import static org.junit.jupiter.api.Assertions.assertNotNull; 26 | import static org.junit.jupiter.api.Assertions.assertTrue; 27 | 28 | public class CoreTest { 29 | @IntegrationTest 30 | public static void testExampleCom() throws IOException { 31 | DnsClient client = new DnsClient(new LruCache(1024)); 32 | String exampleIp4 = "93.184.216.34"; // stable? 33 | String exampleIp6 = "2606:2800:220:1:248:1893:25c8:1946"; // stable? 34 | assertEquals(client.query("example.com", Record.TYPE.A).response.answerSection.get(0).payloadData.toString(), exampleIp4); 35 | assertEquals(client.query("www.example.com", Record.TYPE.A).response.answerSection.get(0).payloadData.toString(), exampleIp4); 36 | assertEquals(client.query("example.com", Record.TYPE.AAAA).response.answerSection.get(0).payloadData.toString(), exampleIp6); 37 | assertEquals(client.query("www.example.com", Record.TYPE.AAAA).response.answerSection.get(0).payloadData.toString(), exampleIp6); 38 | 39 | DnsQueryResult nsResult = client.query("example.com", Record.TYPE.NS); 40 | List values = new ArrayList<>(); 41 | for (Record record : nsResult.response.answerSection) { 42 | values.add(record.payloadData.toString()); 43 | } 44 | Collections.sort(values); 45 | assertEquals(values.get(0), "a.iana-servers.net."); 46 | assertEquals(values.get(1), "b.iana-servers.net."); 47 | } 48 | 49 | @IntegrationTest 50 | public static void testTcpAnswer() throws IOException { 51 | DnsClient client = new DnsClient(new LruCache(1024)); 52 | client.setAskForDnssec(true); 53 | client.setDisableResultFilter(true); 54 | DnsQueryResult result = client.query("www-nsec.example.com", Record.TYPE.A); 55 | assertNotNull(result); 56 | assertTrue(result.response.toArray().length > 512); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /minidns-integration-test/src/main/java/org/minidns/integrationtest/DaneTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.integrationtest; 12 | 13 | import org.minidns.dane.DaneVerifier; 14 | 15 | import javax.net.ssl.HttpsURLConnection; 16 | 17 | import org.junit.Ignore; 18 | 19 | import java.io.IOException; 20 | import java.net.URL; 21 | import java.security.cert.CertificateException; 22 | 23 | public class DaneTest { 24 | 25 | @Ignore 26 | @IntegrationTest 27 | public static void testOarcDaneGood() throws IOException, CertificateException { 28 | DaneVerifier daneVerifier = new DaneVerifier(); 29 | daneVerifier.verifiedConnect((HttpsURLConnection) new URL("https://good.dane.dns-oarc.net/").openConnection()); 30 | } 31 | 32 | @Ignore 33 | @IntegrationTest() 34 | public static void testOarcDaneBadHash() throws IOException, CertificateException { 35 | DaneVerifier daneVerifier = new DaneVerifier(); 36 | daneVerifier.verifiedConnect((HttpsURLConnection) new URL("https://bad-hash.dane.dns-oarc.net/").openConnection()); 37 | } 38 | 39 | @Ignore 40 | @IntegrationTest 41 | public static void testOarcDaneBadParams() throws IOException, CertificateException { 42 | DaneVerifier daneVerifier = new DaneVerifier(); 43 | daneVerifier.verifiedConnect((HttpsURLConnection) new URL("https://bad-params.dane.dns-oarc.net/").openConnection()); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /minidns-integration-test/src/main/java/org/minidns/integrationtest/DnssecTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.integrationtest; 12 | 13 | import java.io.IOException; 14 | import java.util.Iterator; 15 | 16 | import org.junit.Ignore; 17 | import org.minidns.cache.LruCache; 18 | import org.minidns.dnssec.DnssecClient; 19 | import org.minidns.dnssec.DnssecQueryResult; 20 | import org.minidns.dnssec.DnssecUnverifiedReason; 21 | import org.minidns.dnssec.DnssecValidationFailedException; 22 | import org.minidns.record.Record; 23 | 24 | import static org.junit.jupiter.api.Assertions.assertFalse; 25 | 26 | public class DnssecTest { 27 | 28 | @Ignore 29 | @IntegrationTest 30 | public static void testOarcDaneBadSig() throws Exception { 31 | DnssecClient client = new DnssecClient(new LruCache(1024)); 32 | assertFalse(client.queryDnssec("_443._tcp.bad-sig.dane.dns-oarc.net", Record.TYPE.TLSA).isAuthenticData()); 33 | } 34 | 35 | @IntegrationTest 36 | public static void testUniDueSigOk() throws IOException { 37 | DnssecClient client = new DnssecClient(new LruCache(1024)); 38 | assertAuthentic(client.queryDnssec("sigok.verteiltesysteme.net", Record.TYPE.A)); 39 | } 40 | 41 | @IntegrationTest(expected = DnssecValidationFailedException.class) 42 | public static void testUniDueSigFail() throws IOException { 43 | DnssecClient client = new DnssecClient(new LruCache(1024)); 44 | client.query("sigfail.verteiltesysteme.net", Record.TYPE.A); 45 | } 46 | 47 | @IntegrationTest 48 | public static void testCloudFlare() throws IOException { 49 | DnssecClient client = new DnssecClient(new LruCache(1024)); 50 | assertAuthentic(client.queryDnssec("www.cloudflare-dnssec-auth.com", Record.TYPE.A)); 51 | } 52 | 53 | private static void assertAuthentic(DnssecQueryResult dnssecMessage) { 54 | if (dnssecMessage.isAuthenticData()) return; 55 | 56 | StringBuilder sb = new StringBuilder(); 57 | sb.append("Answer should contain authentic data while it does not. Reasons:\n"); 58 | for (Iterator it = dnssecMessage.getUnverifiedReasons().iterator(); it.hasNext(); ) { 59 | DnssecUnverifiedReason unverifiedReason = it.next(); 60 | sb.append(unverifiedReason); 61 | if (it.hasNext()) sb.append('\n'); 62 | } 63 | throw new AssertionError(sb.toString()); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /minidns-integration-test/src/main/java/org/minidns/integrationtest/HlaTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.integrationtest; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertArrayEquals; 14 | import static org.junit.jupiter.api.Assertions.assertEquals; 15 | import static org.junit.jupiter.api.Assertions.assertFalse; 16 | import static org.junit.jupiter.api.Assertions.assertTrue; 17 | 18 | import java.io.IOException; 19 | import java.util.Set; 20 | 21 | import org.minidns.hla.ResolverApi; 22 | import org.minidns.hla.ResolverResult; 23 | import org.minidns.hla.SrvResolverResult; 24 | import org.minidns.record.A; 25 | import org.minidns.record.SRV; 26 | 27 | public class HlaTest { 28 | 29 | @IntegrationTest 30 | public static void resolverTest() throws IOException { 31 | ResolverResult res = ResolverApi.INSTANCE.resolve("geekplace.eu", A.class); 32 | assertEquals(true, res.wasSuccessful()); 33 | Set answers = res.getAnswers(); 34 | assertEquals(1, answers.size()); 35 | assertArrayEquals(new A(5, 45, 100, 158).toByteArray(), answers.iterator().next().toByteArray()); 36 | } 37 | 38 | @IntegrationTest 39 | public static void idnSrvTest() throws IOException { 40 | ResolverResult res = ResolverApi.INSTANCE.resolve("_xmpp-client._tcp.im.plä.net", SRV.class); 41 | Set answers = res.getAnswers(); 42 | assertEquals(1, answers.size()); 43 | 44 | SRV srv = answers.iterator().next(); 45 | 46 | ResolverResult aRes = ResolverApi.INSTANCE.resolve(srv.target, A.class); 47 | 48 | assertTrue(aRes.wasSuccessful()); 49 | } 50 | 51 | @IntegrationTest 52 | public static void resolveSrvTest() throws IOException { 53 | SrvResolverResult resolverResult = ResolverApi.INSTANCE.resolveSrv("_xmpp-client._tcp.jabber.org"); 54 | Set answers = resolverResult.getAnswers(); 55 | assertFalse(answers.isEmpty()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /minidns-integration-test/src/main/java/org/minidns/integrationtest/IntegrationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.integrationtest; 12 | 13 | import java.lang.annotation.ElementType; 14 | import java.lang.annotation.Retention; 15 | import java.lang.annotation.RetentionPolicy; 16 | import java.lang.annotation.Target; 17 | 18 | @Retention(RetentionPolicy.RUNTIME) 19 | @Target(ElementType.METHOD) 20 | public @interface IntegrationTest { 21 | Class expected() default Class.class; 22 | } 23 | -------------------------------------------------------------------------------- /minidns-integration-test/src/main/java/org/minidns/integrationtest/IntegrationTestTools.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.integrationtest; 12 | 13 | import org.minidns.DnsCache; 14 | import org.minidns.cache.ExtendedLruCache; 15 | import org.minidns.cache.FullLruCache; 16 | import org.minidns.cache.LruCache; 17 | import org.minidns.dnssec.DnssecClient; 18 | import org.minidns.source.NetworkDataSourceWithAccounting; 19 | 20 | public class IntegrationTestTools { 21 | 22 | public enum CacheConfig { 23 | without, 24 | normal, 25 | extended, 26 | full, 27 | } 28 | 29 | public static DnssecClient getClient(CacheConfig cacheConfig) { 30 | DnsCache cache; 31 | switch (cacheConfig) { 32 | case without: 33 | cache = null; 34 | break; 35 | case normal: 36 | cache = new LruCache(); 37 | break; 38 | case extended: 39 | cache = new ExtendedLruCache(); 40 | break; 41 | case full: 42 | cache = new FullLruCache(); 43 | break; 44 | default: 45 | throw new IllegalStateException(); 46 | } 47 | 48 | DnssecClient client = new DnssecClient(cache); 49 | client.setDataSource(new NetworkDataSourceWithAccounting()); 50 | return client; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /minidns-integration-test/src/main/java/org/minidns/integrationtest/IterativeDnssecTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.integrationtest; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertTrue; 14 | 15 | import java.io.IOException; 16 | 17 | import org.minidns.dnsname.DnsName; 18 | import org.minidns.dnssec.DnssecClient; 19 | import org.minidns.dnssec.DnssecQueryResult; 20 | import org.minidns.integrationtest.IntegrationTestTools.CacheConfig; 21 | import org.minidns.iterative.ReliableDnsClient.Mode; 22 | import org.minidns.record.Record.TYPE; 23 | import org.minidns.source.NetworkDataSourceWithAccounting; 24 | 25 | public class IterativeDnssecTest { 26 | 27 | private static final DnsName DNSSEC_DOMAIN = IntegrationTestHelper.DNSSEC_DOMAIN; 28 | private static final TYPE RR_TYPE = IntegrationTestHelper.RR_TYPE; 29 | 30 | @IntegrationTest 31 | public static void shouldRequireLessQueries() throws IOException { 32 | DnssecClient normalCacheClient = getClient(CacheConfig.normal); 33 | DnssecQueryResult normalCacheResult = normalCacheClient.queryDnssec(DNSSEC_DOMAIN, RR_TYPE); 34 | assertTrue(normalCacheResult.isAuthenticData()); 35 | NetworkDataSourceWithAccounting normalCacheNdswa = NetworkDataSourceWithAccounting.from(normalCacheClient); 36 | 37 | DnssecClient extendedCacheClient = getClient(CacheConfig.extended); 38 | DnssecQueryResult extendedCacheResult = extendedCacheClient.queryDnssec(DNSSEC_DOMAIN, RR_TYPE); 39 | assertTrue(extendedCacheResult.isAuthenticData()); 40 | NetworkDataSourceWithAccounting extendedCacheNdswa = NetworkDataSourceWithAccounting.from(extendedCacheClient); 41 | 42 | final int normalCacheSuccessfulQueries = normalCacheNdswa.getStats().successfulQueries; 43 | final int extendedCacheSuccessfulQueries = extendedCacheNdswa.getStats().successfulQueries; 44 | assertTrue( 45 | normalCacheSuccessfulQueries > extendedCacheSuccessfulQueries, 46 | "Extend cache successful query count " + extendedCacheSuccessfulQueries 47 | + " is not less than normal cache successful query count " + normalCacheSuccessfulQueries); 48 | } 49 | 50 | private static DnssecClient getClient(CacheConfig cacheConfig) { 51 | DnssecClient client = IntegrationTestTools.getClient(cacheConfig); 52 | client.setMode(Mode.iterativeOnly); 53 | return client; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /minidns-integration-test/src/main/java/org/minidns/integrationtest/NsidTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.integrationtest; 12 | 13 | import java.io.IOException; 14 | import java.net.InetAddress; 15 | 16 | import org.minidns.DnsClient; 17 | import org.minidns.dnsmessage.Question; 18 | import org.minidns.dnsqueryresult.DnsQueryResult; 19 | import org.minidns.dnsmessage.DnsMessage; 20 | import org.minidns.edns.Nsid; 21 | import org.minidns.edns.Edns.OptionCode; 22 | import org.minidns.iterative.IterativeDnsClient; 23 | import org.minidns.record.Record.TYPE; 24 | 25 | import static org.junit.jupiter.api.Assertions.assertNotNull; 26 | 27 | public class NsidTest { 28 | 29 | @IntegrationTest 30 | public static Nsid testNsidLRoot() { 31 | DnsClient client = new DnsClient(null) { 32 | @Override 33 | protected DnsMessage.Builder newQuestion(DnsMessage.Builder message) { 34 | message.getEdnsBuilder().addEdnsOption(Nsid.REQUEST); 35 | return super.newQuestion(message); 36 | } 37 | }; 38 | DnsQueryResult result = null; 39 | Question q = new Question("de", TYPE.NS); 40 | for (InetAddress lRoot : IterativeDnsClient.getRootServer('l')) { 41 | try { 42 | result = client.query(q, lRoot); 43 | } catch (IOException e) { 44 | continue; 45 | } 46 | break; 47 | } 48 | Nsid nsid = result.response.getEdns().getEdnsOption(OptionCode.NSID); 49 | assertNotNull(nsid); 50 | return nsid; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /minidns-integration-test/src/test/java/org/minidns/integrationtest/IntegrationTestTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.integrationtest; 12 | 13 | import org.junit.jupiter.api.Test; 14 | 15 | public class IntegrationTestTest { 16 | /** 17 | * Just here to ensure jacoco is not complaining. 18 | */ 19 | @Test 20 | public void emptyTest() { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /minidns-iterative-resolver/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.minidns.java-conventions' 3 | id 'org.minidns.android-conventions' 4 | } 5 | 6 | description = "A DNS client that can iteratively resolve resource records" 7 | 8 | dependencies { 9 | api project(':minidns-client') 10 | testImplementation project(path: ":minidns-client", configuration: "testRuntime") 11 | } 12 | -------------------------------------------------------------------------------- /minidns-iterative-resolver/src/main/java/org/minidns/iterative/IterativeClientException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.iterative; 12 | 13 | import java.net.InetAddress; 14 | 15 | import org.minidns.MiniDnsException; 16 | import org.minidns.dnsmessage.DnsMessage; 17 | import org.minidns.dnsmessage.Question; 18 | import org.minidns.dnsname.DnsName; 19 | import org.minidns.dnsqueryresult.DnsQueryResult; 20 | 21 | public abstract class IterativeClientException extends MiniDnsException { 22 | 23 | /** 24 | * 25 | */ 26 | private static final long serialVersionUID = 1L; 27 | 28 | protected IterativeClientException(String message) { 29 | super(message); 30 | } 31 | 32 | public static class LoopDetected extends IterativeClientException { 33 | 34 | /** 35 | * 36 | */ 37 | private static final long serialVersionUID = 1L; 38 | 39 | public final InetAddress address; 40 | public final Question question; 41 | 42 | public LoopDetected(InetAddress address, Question question) { 43 | super("Resolution loop detected: We already asked " + address + " about " + question); 44 | this.address = address; 45 | this.question = question; 46 | } 47 | 48 | } 49 | 50 | public static class MaxIterativeStepsReached extends IterativeClientException { 51 | 52 | /** 53 | * 54 | */ 55 | private static final long serialVersionUID = 1L; 56 | 57 | public MaxIterativeStepsReached() { 58 | super("Maxmimum steps reached"); 59 | } 60 | 61 | } 62 | 63 | public static class NotAuthoritativeNorGlueRrFound extends IterativeClientException { 64 | 65 | /** 66 | * 67 | */ 68 | private static final long serialVersionUID = 1L; 69 | 70 | private final DnsMessage request; 71 | private final DnsQueryResult result; 72 | private final DnsName authoritativeZone; 73 | 74 | public NotAuthoritativeNorGlueRrFound(DnsMessage request, DnsQueryResult result, DnsName authoritativeZone) { 75 | super("Did not receive an authoritative answer, nor did the result contain any glue records"); 76 | this.request = request; 77 | this.result = result; 78 | this.authoritativeZone = authoritativeZone; 79 | } 80 | 81 | public DnsMessage getRequest() { 82 | return request; 83 | } 84 | 85 | public DnsQueryResult getResult() { 86 | return result; 87 | } 88 | 89 | public DnsName getAuthoritativeZone() { 90 | return authoritativeZone; 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /minidns-iterative-resolver/src/main/java/org/minidns/iterative/ResolutionState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.iterative; 12 | 13 | import java.net.InetAddress; 14 | import java.util.HashMap; 15 | import java.util.HashSet; 16 | import java.util.Set; 17 | 18 | import org.minidns.dnsmessage.DnsMessage; 19 | import org.minidns.dnsmessage.Question; 20 | import org.minidns.iterative.IterativeClientException.LoopDetected; 21 | import org.minidns.iterative.IterativeClientException.MaxIterativeStepsReached; 22 | 23 | public class ResolutionState { 24 | 25 | private final IterativeDnsClient recursiveDnsClient; 26 | private final HashMap> map = new HashMap<>(); 27 | private int steps; 28 | 29 | ResolutionState(IterativeDnsClient recursiveDnsClient) { 30 | this.recursiveDnsClient = recursiveDnsClient; 31 | } 32 | 33 | void recurse(InetAddress address, DnsMessage query) throws LoopDetected, MaxIterativeStepsReached { 34 | Question question = query.getQuestion(); 35 | if (!map.containsKey(address)) { 36 | map.put(address, new HashSet()); 37 | } else if (map.get(address).contains(question)) { 38 | throw new IterativeClientException.LoopDetected(address, question); 39 | } 40 | 41 | if (++steps > recursiveDnsClient.maxSteps) { 42 | throw new IterativeClientException.MaxIterativeStepsReached(); 43 | } 44 | 45 | boolean isNew = map.get(address).add(question); 46 | assert isNew; 47 | } 48 | 49 | void decrementSteps() { 50 | steps--; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /minidns-repl/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.minidns.java-conventions' 3 | id "com.github.alisiikh.scalastyle" version "3.5.0" 4 | } 5 | 6 | description = "A read-eval-print loop (REPL) for MiniDNS" 7 | 8 | apply plugin: 'scala' 9 | apply plugin: 'com.github.alisiikh.scalastyle' 10 | 11 | ext { 12 | scalaVersion = '2.13.13' 13 | } 14 | 15 | dependencies { 16 | api project(':minidns-client') 17 | api project(':minidns-iterative-resolver') 18 | api project(':minidns-dnssec') 19 | api project(':minidns-integration-test') 20 | api project(':minidns-hla') 21 | implementation "com.lihaoyi:ammonite_$scalaVersion:3.0.0-M1" 22 | testImplementation project(path: ":minidns-client", configuration: "testRuntime") 23 | } 24 | 25 | scalastyle { 26 | config = new File(rootConfigDir, 'scalaStyle.xml') 27 | verbose = true 28 | failOnWarning = true 29 | } 30 | 31 | check.dependsOn(scalastyleCheck) 32 | 33 | task printClasspath(dependsOn: assemble) { 34 | doLast { 35 | println sourceSets.main.runtimeClasspath.asPath 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /minidns-repl/scala.repl: -------------------------------------------------------------------------------- 1 | org.minidns.minidnsrepl.MiniDnsRepl.init() 2 | 3 | import org.minidns._ 4 | import org.minidns.dnsmessage._ 5 | import org.minidns.record.Record.TYPE 6 | import org.minidns.record._ 7 | 8 | import org.minidns.dnssec.DnssecClient 9 | 10 | import org.minidns.minidnsrepl.MiniDnsRepl.clearCache 11 | import org.minidns.minidnsrepl.MiniDnsRepl.writeToFile 12 | 13 | import org.minidns.minidnsrepl.MiniDnsStats._ 14 | 15 | import org.minidns.jul.MiniDnsJul._ 16 | 17 | import java.net.InetAddress 18 | 19 | import java.util.logging._ 20 | 21 | def debugLog() = { 22 | val miniDnsLogger = Logger.getLogger("org.minidns") 23 | miniDnsLogger.setLevel(Level.FINE) 24 | val consoleHandler = new ConsoleHandler() 25 | consoleHandler.setLevel(Level.FINE) 26 | miniDnsLogger.addHandler(consoleHandler) 27 | } 28 | 29 | // Some standard values 30 | Predef.println("Set value 'c' to DNSClient") 31 | val c = org.minidns.minidnsrepl.MiniDnsRepl.DNSCLIENT 32 | Predef.println("Set value 'ic' to IterativeDnsClient") 33 | val ic = org.minidns.minidnsrepl.MiniDnsRepl.ITERATIVEDNSCLIENT 34 | Predef.println("Set value 'dc' to DnssecClient") 35 | val dc = org.minidns.minidnsrepl.MiniDnsRepl.DNSSECCLIENT 36 | // A normal resolver 37 | Predef.println("Set value 'r' to ResolverApi") 38 | val r = org.minidns.hla.ResolverApi.INSTANCE 39 | // A DNSSEC resolver 40 | Predef.println("Set value 'dr' to DnssecResolverApi") 41 | val dr = org.minidns.hla.DnssecResolverApi.INSTANCE 42 | 43 | Predef.println("Enjoy MiniDNS. Go ahead and try a query. For example:") 44 | Predef.println("c query (\"geekplace.eu\", TYPE.A)") 45 | Predef.println("dr resolveDnssecReliable (\"verteiltesysteme.net\", classOf[A])") 46 | Predef.println("NOTE: You can enable debug log output by calling 'debugLog'") 47 | 48 | -------------------------------------------------------------------------------- /minidns-repl/src/main/java/org/minidns/minidnsrepl/DnssecStats.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.minidnsrepl; 12 | 13 | import java.io.IOException; 14 | 15 | import org.minidns.cache.ExtendedLruCache; 16 | import org.minidns.dnsname.DnsName; 17 | import org.minidns.dnssec.DnssecClient; 18 | import org.minidns.dnssec.DnssecQueryResult; 19 | import org.minidns.dnssec.DnssecUnverifiedReason; 20 | import org.minidns.integrationtest.IntegrationTestTools.CacheConfig; 21 | import org.minidns.iterative.ReliableDnsClient.Mode; 22 | import org.minidns.jul.MiniDnsJul; 23 | import org.minidns.record.Record.TYPE; 24 | 25 | public class DnssecStats { 26 | 27 | private static final DnsName DOMAIN = DnsName.from("verteiltesysteme.net"); 28 | private static final TYPE RR_TYPE = TYPE.A; 29 | 30 | public static void iterativeDnssecLookupNormalVsExtendedCache() throws IOException { 31 | // iterativeDnssecLookup(CacheConfig.normal); 32 | iterativeDnssecLookup(CacheConfig.extended); 33 | } 34 | 35 | private static void iterativeDnssecLookup(CacheConfig cacheConfig) throws IOException { 36 | DnssecClient client = MiniDnsStats.getClient(cacheConfig); 37 | client.setMode(Mode.iterativeOnly); 38 | DnssecQueryResult secRes = client.queryDnssec(DOMAIN, RR_TYPE); 39 | 40 | StringBuilder stats = MiniDnsStats.getStats(client); 41 | stats.append('\n'); 42 | stats.append(secRes); 43 | stats.append('\n'); 44 | for (DnssecUnverifiedReason r : secRes.getUnverifiedReasons()) { 45 | stats.append(r); 46 | } 47 | stats.append("\n\n"); 48 | // CHECKSTYLE:OFF 49 | System.out.println(stats); 50 | // CHECKSTYLE:ON 51 | } 52 | 53 | public static void iterativeDnsssecTest() throws SecurityException, IllegalArgumentException, IOException { 54 | MiniDnsJul.enableMiniDnsTrace(); 55 | DnssecClient client = new DnssecClient(new ExtendedLruCache()); 56 | client.setMode(Mode.iterativeOnly); 57 | 58 | DnssecQueryResult secRes = client.queryDnssec("verteiltesysteme.net", TYPE.A); 59 | 60 | // CHECKSTYLE:OFF 61 | System.out.println(secRes); 62 | // CHECKSTYLE:ON 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /minidns-repl/src/main/java/org/minidns/minidnsrepl/MiniDnsRepl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.minidnsrepl; 12 | 13 | import java.io.FileOutputStream; 14 | import java.io.IOException; 15 | import java.lang.reflect.Field; 16 | 17 | import org.minidns.AbstractDnsClient; 18 | import org.minidns.DnsClient; 19 | import org.minidns.cache.LruCache; 20 | import org.minidns.dnsmessage.DnsMessage; 21 | import org.minidns.dnssec.DnssecClient; 22 | import org.minidns.hla.DnssecResolverApi; 23 | import org.minidns.hla.ResolverResult; 24 | import org.minidns.iterative.IterativeDnsClient; 25 | import org.minidns.jul.MiniDnsJul; 26 | import org.minidns.record.A; 27 | 28 | public class MiniDnsRepl { 29 | 30 | public static final DnsClient DNSCLIENT = new DnsClient(); 31 | public static final IterativeDnsClient ITERATIVEDNSCLIENT = new IterativeDnsClient(); 32 | public static final DnssecClient DNSSECCLIENT = new DnssecClient(); 33 | 34 | static { 35 | LruCache cache = null; 36 | try { 37 | Field defaultCacheField = AbstractDnsClient.class.getDeclaredField("DEFAULT_CACHE"); 38 | defaultCacheField.setAccessible(true); 39 | cache = (LruCache) defaultCacheField.get(null); 40 | } catch (IllegalAccessException | NoSuchFieldException | SecurityException e) { 41 | throw new IllegalStateException(e); 42 | } 43 | DEFAULT_CACHE = cache; 44 | } 45 | 46 | public static final LruCache DEFAULT_CACHE; 47 | 48 | public static void init() { 49 | // CHECKSTYLE:OFF 50 | System.out.println("MiniDNS REPL"); 51 | // CHECKSTYLE:ON 52 | } 53 | 54 | public static void clearCache() throws SecurityException, IllegalArgumentException { 55 | DEFAULT_CACHE.clear(); 56 | } 57 | 58 | public static void main(String[] args) throws IOException, SecurityException, IllegalArgumentException { 59 | MiniDnsJul.enableMiniDnsTrace(); 60 | 61 | ResolverResult res = DnssecResolverApi.INSTANCE.resolveDnssecReliable("verteiltesysteme.net", A.class); 62 | /* 63 | DnssecStats.iterativeDnssecLookupNormalVsExtendedCache(); 64 | DnssecClient client = new DNSSECClient(new LRUCache(1024)); 65 | DnssecMessage secRes = client.queryDnssec("verteiltesysteme.net", TYPE.A); 66 | */ 67 | 68 | /* 69 | DnssecStats.iterativeDnssecLookupNormalVsExtendedCache(); 70 | Nsid nsid = NSIDTest.testNsidLRoot(); 71 | DnsMessage res = RECURSIVEDNSCLIENT.query("mate.geekplace.eu", TYPE.A); 72 | */ 73 | // CHECKSTYLE:OFF 74 | System.out.println(res); 75 | // System.out.println(nsid); 76 | // System.out.println(secRes); 77 | // System.out.println(res); 78 | // CHCECKSTYLE:ON 79 | } 80 | 81 | public static void writeToFile(DnsMessage dnsMessage, String path) throws IOException { 82 | try (FileOutputStream fos = new FileOutputStream(path)) { 83 | dnsMessage.writeTo(fos, true); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /minidns-repl/src/test/java/org/minidns/minidnsrepl/ReplTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2024 the original author or authors 3 | * 4 | * This software is licensed under the Apache License, Version 2.0, 5 | * the GNU Lesser General Public License version 2 or later ("LGPL") 6 | * and the WTFPL. 7 | * You may choose either license to govern your use of this software only 8 | * upon the condition that you accept all of the terms of either 9 | * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 10 | */ 11 | package org.minidns.minidnsrepl; 12 | 13 | import org.junit.jupiter.api.Test; 14 | 15 | public class ReplTest { 16 | /** 17 | * Just here to ensure jacoco is not complaining. 18 | */ 19 | @Test 20 | public void emptyTest() { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /misc/resolve.pl: -------------------------------------------------------------------------------- 1 | use Net::DNS; 2 | 3 | my $r = Net::DNS::Resolver->new(); 4 | 5 | # This script is provided as a reference. It's not really part of the 6 | # minidns source code. Rather, the files it downloaded when _I_ ran it 7 | # today form part of the source, and the junit tests verify that 8 | # minidns interprets those exact packets the same way that I do. 9 | 10 | # If you rerun the script, you may get other results than I did in 11 | # January 2015. Several of them likely depend on geolocation and load 12 | # balancing. 13 | 14 | # In short: If you update the packets you'll have to interpret them 15 | # correctly and update the interpretation tests appropriately. 16 | 17 | 18 | # do one DNS lookup and write the query packet to a file 19 | 20 | sub lookup() { 21 | my ($domain, $type, $filename) = @_; 22 | 23 | my $p = $r->query($domain, $type); 24 | 25 | # print for visibility during test analysis 26 | print $p->string; 27 | 28 | open F, ">$filename" or die "$!\n"; 29 | print F $p->data; 30 | close F; 31 | } 32 | 33 | 34 | # SRV and MX are near and dear to me 35 | 36 | &lookup("gmail.com", "mx", "gmail-mx"); 37 | &lookup("_xmpp-client._tcp.gulbrandsen.priv.no", "srv", "gpn-srv"); 38 | 39 | # A matters to everyone 40 | 41 | # sunracle uses a CNAME now, which affords an opportunity to test for 42 | # an attack 43 | &lookup("www.sun.com", "a", "sun-a"); 44 | # we'll modify the answer and change one AD RR, and then check that a 45 | # direct lookup is not affected (ie. our cache isn't poisoned) 46 | &lookup("legacy-sun.oraclegha.com", "a", "sun-real-a"); 47 | 48 | # AAAA doubles in importance every few months 49 | &lookup("google.com", "aaaa", "google-aaaa"); 50 | 51 | &lookup("oracle.com", "soa", "oracle-soa"); 52 | -------------------------------------------------------------------------------- /misc/sbt/.gitignore: -------------------------------------------------------------------------------- 1 | /project/ 2 | /target/ 3 | -------------------------------------------------------------------------------- /misc/sbt/build.sbt: -------------------------------------------------------------------------------- 1 | name := "MiniDNS Playground for Scala" 2 | 3 | version := "1.0" 4 | 5 | resolvers += Resolver.sonatypeRepo("snapshots") 6 | resolvers += Resolver.mavenLocal 7 | 8 | libraryDependencies += "org.minidns" % "minidns-client" % "latest.integration" 9 | libraryDependencies += "org.minidns" % "minidns-dnssec" % "latest.integration" 10 | 11 | initialCommands in console += "import org.minidns._;" 12 | initialCommands in console += "import org.minidns.Record.TYPE;" 13 | initialCommands in console += "val client = new DnsClient(new java.util.HashMap[Question,DnsMessage]())" 14 | 15 | -------------------------------------------------------------------------------- /repl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | JDWP=false 5 | JDWP_PORT=8000 6 | 7 | while getopts djp: OPTION "$@"; do 8 | case $OPTION in 9 | d) 10 | set -x 11 | ;; 12 | j) 13 | JDWP=true 14 | ;; 15 | p) 16 | JDWP_PORT=$OPTARG 17 | ;; 18 | esac 19 | done 20 | 21 | EXTRA_JAVA_ARGS=() 22 | if $JDWP; then 23 | EXTRA_JAVA_ARGS+=("-Xdebug") 24 | EXTRA_JAVA_ARGS+=("-Xrunjdwp:server=y,transport=dt_socket,address=${JDWP_PORT},suspend=n") 25 | fi 26 | 27 | PROJECT_ROOT=$(dirname "${BASH_SOURCE[0]}") 28 | cd "${PROJECT_ROOT}" 29 | 30 | echo "Compiling and computing classpath (May take a while)" 31 | # Sadly even with the --quiet option Gradle (or some component of) 32 | # will print the number of warnings/errors to stdout if there are 33 | # any. So the result could look like 34 | # 52 warnings\n1 warning\n12 warnings\n 35 | # /smack/smack-repl/build/classes/main:/smack/smack-repl/build/ 36 | # resources/main:/smack/smack-tcp/build/libs/smack-tcp-4.2.0-alpha4-SNAPSHOT.jar 37 | # So perform a "tail -n1" on the output of gradle 38 | GRADLE_CLASSPATH="$(${GRADLE_BIN:-./gradlew} :minidns-repl:printClasspath --quiet |\ 39 | tail -n1)" 40 | echo "Finished, starting REPL" 41 | 42 | exec java \ 43 | "${EXTRA_JAVA_ARGS[@]}" \ 44 | -Dscala.usejavacp=true \ 45 | -classpath "${GRADLE_CLASSPATH}" \ 46 | ammonite.Main \ 47 | --predef minidns-repl/scala.repl 48 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | includeBuild('build-logic') 3 | } 4 | 5 | // The name of the root project. 6 | // If we would not set the name, then gradle would use the directory 7 | // name of the root directory 8 | rootProject.name = 'MiniDNS' 9 | 10 | include 'minidns-core' 11 | include 'minidns-client' 12 | include 'minidns-async' 13 | include 'minidns-iterative-resolver' 14 | include 'minidns-dnssec' 15 | include 'minidns-dane' 16 | include 'minidns-integration-test' 17 | include 'minidns-repl' 18 | include 'minidns-hla' 19 | include 'minidns-android23' 20 | -------------------------------------------------------------------------------- /version: -------------------------------------------------------------------------------- 1 | 1.1.2-SNAPSHOT 2 | --------------------------------------------------------------------------------