Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package dnsdiag for openSUSE:Factory checked in at 2026-02-06 19:10:35 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/dnsdiag (Old) and /work/SRC/openSUSE:Factory/.dnsdiag.new.1670 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "dnsdiag" Fri Feb 6 19:10:35 2026 rev:13 rq:1331550 version:2.9.3 Changes: -------- --- /work/SRC/openSUSE:Factory/dnsdiag/dnsdiag.changes 2026-01-18 22:22:11.747816616 +0100 +++ /work/SRC/openSUSE:Factory/.dnsdiag.new.1670/dnsdiag.changes 2026-02-06 19:17:10.381345730 +0100 @@ -1,0 +2,45 @@ +Tue Feb 3 18:44:15 UTC 2026 - Martin Hauke <[email protected]> + +- Update to version 2.9.3 + Bug Fixes + * TCP Traceroute Fixed: The most important fix in this release + resolves a regression where dnstraceroute with TCP protocol + (-T flag) would immediately fail with "No route to host" errors + During TCP traceroute operations, intermediate hosts send ICMP + Time Exceeded messages when TTL expires, which the TCP stack + interprets as EHOSTUNREACH errors. These errors were being + unconditionally re-raised even in traceroute mode where they're + expected behavior. The fix now properly handles these errors + during traceroute, allowing TCP path discovery to work as + intended. + * QUIC and HTTP/3 Traceroute TTL Control: Previously, + dnstraceroute couldn't control TTL values when using QUIC (-Q) + or HTTP/3 (-3) protocols, basically breaking traceroute + functionality for DoH3 and DoQ. The fix enables proper TTL + manipulation for both protocols, allowing users to trace + network paths to DNS-over-QUIC and DNS-over-HTTP/3 resolvers. + * Timing Accuracy Improvements: Replaced dnspython library + internal timing with Python's perf_counter for response time + measurements across all DNS protocols. This provides more + accurate and consistent latency measurements. + * Better Error Handling for Modern Protocols: Improved error + handling for DoH, DoH3, and DoQ protocols to display + user-friendly error messages instead of Python stack traces. + Connection refused errors are now treated as transient across + all DNS protocols, and transient QUIC connection failures + (UnexpectedEOF exceptions) are handled gracefully, allowing + dnsping to continue with the next attempt. + * DNSSEC Information Display: Added explanation of DNSSEC flags + and Extended DNS Error (EDE) codes in dnsping output. When + DNSSEC validation is enabled, users now see detailed + explanations of response codes like "DNSSEC Bogus" with + human-readable descriptions of what went wrong, making DNSSEC + troubleshooting easier. + * Command-Line Parameter Validation: Added mutual exclusivity + validation to command-line parameters across all tools. + Conflicting protocol flags (like -T and -H used together) now + trigger clear error messages instead of unpredictable behavior, + preventing user confusion and potential misdiagnosis of DNS + issues. + +------------------------------------------------------------------- Old: ---- dnsdiag-2.9.2.tar.gz New: ---- dnsdiag-2.9.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ dnsdiag.spec ++++++ --- /var/tmp/diff_new_pack.YLdfJR/_old 2026-02-06 19:17:11.965412751 +0100 +++ /var/tmp/diff_new_pack.YLdfJR/_new 2026-02-06 19:17:11.977413259 +0100 @@ -20,7 +20,7 @@ %define pythons python3 %bcond_with test Name: dnsdiag -Version: 2.9.2 +Version: 2.9.3 Release: 0 Summary: DNS request auditing toolset License: BSD-3-Clause ++++++ dnsdiag-2.9.2.tar.gz -> dnsdiag-2.9.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.9.2/.github/workflows/build-release.yml new/dnsdiag-2.9.3/.github/workflows/build-release.yml --- old/dnsdiag-2.9.2/.github/workflows/build-release.yml 2026-01-13 11:12:08.000000000 +0100 +++ new/dnsdiag-2.9.3/.github/workflows/build-release.yml 2026-02-03 18:18:21.000000000 +0100 @@ -2,133 +2,44 @@ on: workflow_dispatch: - inputs: - version: - description: 'Version to build (leave empty to auto-detect from code)' - required: false - type: string permissions: contents: read jobs: build-artifacts: - name: Build ${{ matrix.platform }} binary + name: Build ${{ matrix.os }} binary runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - include: - # Linux x86_64 - - os: ubuntu-latest - platform: linux-x86_64 - shell: bash - - # Linux ARM64 - - os: ubuntu-24.04-arm - platform: linux-arm64 - shell: bash - - # macOS Intel x86_64 - - os: macos-15-intel - platform: darwin-x86_64 - shell: bash - - # macOS Apple Silicon ARM64 - - os: macos-latest - platform: darwin-arm64 - shell: bash - - # Windows x86_64 - - os: windows-latest - platform: win-amd64 - shell: bash - - # Windows ARM64 - - os: windows-11-arm - platform: win-arm64 - shell: bash + os: [ubuntu-latest, ubuntu-24.04-arm, macos-15-intel, macos-latest, windows-latest] defaults: run: - shell: ${{ matrix.shell }} + shell: bash steps: - - name: Checkout code - uses: actions/checkout@v5 + - uses: actions/checkout@v5 - - name: Set up Python 3.14 - uses: actions/setup-python@v6 + - uses: actions/setup-python@v6 with: python-version: "3.14" cache: 'pip' cache-dependency-path: 'requirements.txt' - - name: Install build dependencies - run: | - python -m pip install --upgrade pip || exit 1 - pip install virtualenv || exit 1 + - name: Install virtualenv + run: pip install virtualenv - - name: Install UPX (Ubuntu only) + - name: Install UPX (Linux only) if: runner.os == 'Linux' - run: | - sudo apt-get update - sudo apt-get install -y upx - - - name: Extract version from code - id: get_version - run: | - if [ -n "${{ inputs.version }}" ]; then - VERSION="${{ inputs.version }}" - else - VERSION=$(python3 -c "import sys; sys.path.insert(0, '.'); from dnsdiag.shared import __version__; print(__version__)") - fi - echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - echo "Building version: $VERSION" + run: sudo apt-get update && sudo apt-get install -y upx - name: Build package - run: | - bash build-pkgs.sh --venv + run: bash build-pkgs.sh --venv - - name: List built packages - run: | - echo "Built packages:" - ls -lh pkg/ - - - name: Upload artifacts - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v4 with: - name: dnsdiag-${{ matrix.platform }}-bin - path: | - pkg/*.tar.gz - pkg/*.zip - retention-days: 30 + name: ${{ matrix.os }}-package + path: pkg/* if-no-files-found: error - - summary: - name: Build Summary - needs: build-artifacts - runs-on: ubuntu-latest - steps: - - name: Generate summary - run: | - echo "## Release Build Complete" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "Binary packages have been built for the following platforms:" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "- Linux x86_64" >> $GITHUB_STEP_SUMMARY - echo "- Linux ARM64" >> $GITHUB_STEP_SUMMARY - echo "- macOS Intel x86_64" >> $GITHUB_STEP_SUMMARY - echo "- macOS Apple Silicon ARM64" >> $GITHUB_STEP_SUMMARY - echo "- Windows x86_64" >> $GITHUB_STEP_SUMMARY - echo "- Windows ARM64" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### Next Steps:" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "1. Download artifacts from the workflow run (6 packages total)" >> $GITHUB_STEP_SUMMARY - echo "2. GPG sign each package (.tar.gz/.zip files)" >> $GITHUB_STEP_SUMMARY - echo "3. Build FreeBSD package manually (not available on GitHub runners)" >> $GITHUB_STEP_SUMMARY - echo "4. Create GitHub release and upload all signed packages" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### Manual Build Required:" >> $GITHUB_STEP_SUMMARY - echo "FreeBSD packages must still be built manually (GitHub does not provide FreeBSD runners)" >> $GITHUB_STEP_SUMMARY diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.9.2/.github/workflows/packages.yml new/dnsdiag-2.9.3/.github/workflows/packages.yml --- old/dnsdiag-2.9.2/.github/workflows/packages.yml 2026-01-13 11:12:08.000000000 +0100 +++ new/dnsdiag-2.9.3/.github/workflows/packages.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,37 +0,0 @@ -name: Package Build - -on: - push: - tags: - - 'v*' - -jobs: - build: - - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] - - steps: - - uses: actions/checkout@v5 - with: - fetch-depth: 0 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v6 - with: - python-version: ${{ matrix.python-version }} - cache: 'pip' - cache-dependency-path: 'requirements.txt' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install pyinstaller - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - # Note: Linting and type checking are performed in tests.yml workflow - # to avoid redundant checks. This workflow focuses on building packages. - - - name: Build package - run: | - sh build-pkgs.sh diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.9.2/.github/workflows/tests.yml new/dnsdiag-2.9.3/.github/workflows/tests.yml --- old/dnsdiag-2.9.2/.github/workflows/tests.yml 2026-01-13 11:12:08.000000000 +0100 +++ new/dnsdiag-2.9.3/.github/workflows/tests.yml 2026-02-03 18:18:21.000000000 +0100 @@ -77,14 +77,8 @@ fail-fast: false matrix: # Full OS coverage for critical Python versions - os: [ubuntu-latest, ubuntu-24.04-arm, macos-15-intel, macos-latest, windows-latest, windows-11-arm] + os: [ubuntu-latest, ubuntu-24.04-arm, macos-15-intel, macos-latest, windows-latest] python-version: ["3.10", "3.13", "3.14"] - exclude: - # Python 3.10 and 3.13 not available on Windows ARM64 (only 3.14+) - - os: windows-11-arm - python-version: "3.10" - - os: windows-11-arm - python-version: "3.13" steps: - uses: actions/checkout@v5 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.9.2/CHANGELOG.md new/dnsdiag-2.9.3/CHANGELOG.md --- old/dnsdiag-2.9.2/CHANGELOG.md 2026-01-13 11:12:08.000000000 +0100 +++ new/dnsdiag-2.9.3/CHANGELOG.md 2026-02-03 18:18:21.000000000 +0100 @@ -6,6 +6,269 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). <!-- insertion marker --> +## [v2.9.3](https://github.com/farrokhi/dnsdiag/releases/tag/v2.9.3) - 2026-02-03 + +<small>[Compare with v2.9.2](https://github.com/farrokhi/dnsdiag/compare/v2.9.2...v2.9.3)</small> + +### Added + +- Add explanation of DNSSEC flags and EDE codes in dnsping output (#155) ([81c50bc](https://github.com/farrokhi/dnsdiag/commit/81c50bc3be7aa82e264a4f13d3f1ef09399b59b0) by [@jeremyrayjewell](https://github.com/jeremyrayjewell)). +- Add mutual exclusivity to command line parameters (#156) ([21a6a3b](https://github.com/farrokhi/dnsdiag/commit/21a6a3bb1dbbb3e61bd29b9575de86ca2ff44ed1) by [@farrokhi](https://github.com/farrokhi)). + +### Fixed + +- fix(dnstraceroute): handle expected network errors during TCP traceroute ([6950488](https://github.com/farrokhi/dnsdiag/commit/69504884e8d0f585c1ce0f579f64e824d3856670) by [@farrokhi](https://github.com/farrokhi)). +- fix(dnstraceroute): enable TTL control for QUIC and HTTP/3 protocols (#157) ([d2ba23c](https://github.com/farrokhi/dnsdiag/commit/d2ba23ca1c681a21113704384b8a6c7cebe735eb) by [@farrokhi](https://github.com/farrokhi)). +- fix: remove Windows ARM64 from CI build matrix ([04f8b62](https://github.com/farrokhi/dnsdiag/commit/04f8b6243fdf803538e2bcea85faee386434be9a) by [@farrokhi](https://github.com/farrokhi)). +- fix: replace unreliable dnspython timing with perf_counter measurements ([0a3a5f6](https://github.com/farrokhi/dnsdiag/commit/0a3a5f6a723a71ec65a5be47cfb83001899d3262) by [@farrokhi](https://github.com/farrokhi)). +- fix: improved error handling for DoH, DoH3 and DoQ ([6d14c1f](https://github.com/farrokhi/dnsdiag/commit/6d14c1f78fa9715e4c962d829f38f8472c43ad42) by [@farrokhi](https://github.com/farrokhi)). +- fix: treat connection refused as transient across all DNS protocols ([099d627](https://github.com/farrokhi/dnsdiag/commit/099d627b4c683682f712ba5c749ff6ca2fc80185) by [@farrokhi](https://github.com/farrokhi)). +- fix: handle transient QUIC connection failures gracefully ([87b2285](https://github.com/farrokhi/dnsdiag/commit/87b2285149c23b9758d332ef811c1970e407f2d6) by [@farrokhi](https://github.com/farrokhi)). +- fix: detect Windows ARM64 architecture correctly in build script ([19f3dc2](https://github.com/farrokhi/dnsdiag/commit/19f3dc2eebc3da8c29dde26df09fe593c6b63aa2) by [@farrokhi](https://github.com/farrokhi)). + +<!-- insertion marker --> +## [v2.9.2](https://github.com/farrokhi/dnsdiag/releases/tag/v2.9.2) - 2026-01-13 + +<small>[Compare with v2.9.1](https://github.com/farrokhi/dnsdiag/compare/v2.9.1...v2.9.2)</small> + +### Fixed + +- fix: add missing import to unbreak tests ([b3ca60a](https://github.com/farrokhi/dnsdiag/commit/b3ca60a8924317264f8fdd579dbc6cfa20fb023b) by [@farrokhi](https://github.com/farrokhi)). +- fix: output valid JSONL instead of concatenated JSON objects ([7b3f55c](https://github.com/farrokhi/dnsdiag/commit/7b3f55c7dbb81cb8d4b261572f1417b9982f9c53) by [@farrokhi](https://github.com/farrokhi)). +- fix: use bytes for NSID EDNS option instead of string ([4bccff6](https://github.com/farrokhi/dnsdiag/commit/4bccff67968fae72d63dff446fcf767bb6d969d5) by [@farrokhi](https://github.com/farrokhi)). +- fix: show first answer with record type in -a flag output ([076d81f](https://github.com/farrokhi/dnsdiag/commit/076d81fd952689d63ea29451d943078e6c32db7c) by [@farrokhi](https://github.com/farrokhi)). +- fix: tests now use sys.executable instead of playing python roulette ([9a85033](https://github.com/farrokhi/dnsdiag/commit/9a85033573816722f6f1cd405eb55fb202f8eced) by [@farrokhi](https://github.com/farrokhi)). +- fix: survive network status changes instead of dying ([42e520a](https://github.com/farrokhi/dnsdiag/commit/42e520a1bd6a877d69611a61d9f71412c0ee1ed3) by [@farrokhi](https://github.com/farrokhi)). +- fix: return exit code 0 for --help flag ([4ecf76a](https://github.com/farrokhi/dnsdiag/commit/4ecf76af24bba1369aa05a906f2a98af949d3cef) by [@farrokhi](https://github.com/farrokhi)). +- fix: install virtualenv dependency in build release workflow ([204a256](https://github.com/farrokhi/dnsdiag/commit/204a2567ac18756e16a6542a639ecc4a0f83ad11) by [@farrokhi](https://github.com/farrokhi)). +- fix: handle dependency installation failures and relax cryptography constraint ([4a7575e](https://github.com/farrokhi/dnsdiag/commit/4a7575e4fb19921387b912975f589b8f8a2de3e0) by [@farrokhi](https://github.com/farrokhi)). +- fix: handle network restrictions on ARM64 GitHub Actions runners ([c2df8a9](https://github.com/farrokhi/dnsdiag/commit/c2df8a9688b86ff684912db3dbd3fc218713623c) by [@farrokhi](https://github.com/farrokhi)). +- fix: exclude Python 3.10 and 3.13 from Windows ARM64 runners ([524cfbf](https://github.com/farrokhi/dnsdiag/commit/524cfbf261bb167441e810184db18c8fcd266011) by [@farrokhi](https://github.com/farrokhi)). +- fix: prevent negative sleep duration in interruptible sleep loop ([6bc00ab](https://github.com/farrokhi/dnsdiag/commit/6bc00ab5202e22719252bb27d3c89d6fd3e57dab) by [@farrokhi](https://github.com/farrokhi)). + +## [v2.9.1](https://github.com/farrokhi/dnsdiag/releases/tag/v2.9.1) - 2025-10-31 + +<small>[Compare with v2.9.0](https://github.com/farrokhi/dnsdiag/compare/v2.9.0...v2.9.1)</small> + +### Fixed + +- fix: truncate cookie display in normal mode to 8 characters ([6d8f609](https://github.com/farrokhi/dnsdiag/commit/6d8f6098cdf666bd2cbf6ad5805bafdabec99cb3) by [@farrokhi](https://github.com/farrokhi)). +- fix: include root-level Python modules in package distribution ([0470053](https://github.com/farrokhi/dnsdiag/commit/047005321125a5393eebdb0f24e792e07e85cde3) by [@farrokhi](https://github.com/farrokhi)). + +## [v2.9.0](https://github.com/farrokhi/dnsdiag/releases/tag/v2.9.0) - 2025-10-26 + +<small>[Compare with v2.8.1](https://github.com/farrokhi/dnsdiag/compare/v2.8.1...v2.9.0)</small> + +### Added + +- Add --nsid support to dnstraceroute (#153) ([85d96f6](https://github.com/farrokhi/dnsdiag/commit/85d96f66d2cfa36d5fd47d2fb5022f269e23aecb) by [@farrokhi](https://github.com/farrokhi)). +- Add tests for cookie feature in dnsping ([66b4faa](https://github.com/farrokhi/dnsdiag/commit/66b4faa80fbf8b2cbe94e8f73e942400715a40ef) by [@farrokhi](https://github.com/farrokhi)). +- Add support for Python 3.14 ([8099260](https://github.com/farrokhi/dnsdiag/commit/8099260c69d159844c2790bdd0064e943c847e03) by [@farrokhi](https://github.com/farrokhi)). +- Add marker to disable IPv6 tests on Github Action ([a756d10](https://github.com/farrokhi/dnsdiag/commit/a756d10bc22b57ad00273200528b1955c73271f0) by [@farrokhi](https://github.com/farrokhi)). +- Add Windows to test suite ([1e1cbdb](https://github.com/farrokhi/dnsdiag/commit/1e1cbdb5f745a67bddaabf9cc83da5b755115f7b) by [@farrokhi](https://github.com/farrokhi)). +- Add GitHub Actions workflow for running pytest integration tests ([4f4021c](https://github.com/farrokhi/dnsdiag/commit/4f4021c0fd51ce36017dee0884ec44cdc3981e08) by [@farrokhi](https://github.com/farrokhi)). +- Add type checking to tests ([93324be](https://github.com/farrokhi/dnsdiag/commit/93324beb7bc36299da02d32400eb460f1e72855d) by [@farrokhi](https://github.com/farrokhi)). +- Add a more realistic and up to date dnseval output ([777c6f5](https://github.com/farrokhi/dnsdiag/commit/777c6f564e8fd3840a84fb946a792b8744363d59) by [@farrokhi](https://github.com/farrokhi)). +- Add json to dnseval tests ([162d7b1](https://github.com/farrokhi/dnsdiag/commit/162d7b1b0fa4be264c90711b843751c6e4fb60aa) by [@farrokhi](https://github.com/farrokhi)). +- Add EDNS flags display and improve output formatting in dnseval ([2316f77](https://github.com/farrokhi/dnsdiag/commit/2316f77557fec432764870a3227e94aead6cbca0) by [@farrokhi](https://github.com/farrokhi)). +- Add missing cli parameters in syntax help ([da46a1b](https://github.com/farrokhi/dnsdiag/commit/da46a1bf05305e7c852874502587215f01c586b0) by [@farrokhi](https://github.com/farrokhi)). +- Add DoQ and DoH3 protocol support to dnseval (#139) ([51e6fc8](https://github.com/farrokhi/dnsdiag/commit/51e6fc808404cf363138d81251815bfe6f600bee) by [@farrokhi](https://github.com/farrokhi)). +- Add type hints to shared DNS module and fix type syntax errors (#136) ([cda3402](https://github.com/farrokhi/dnsdiag/commit/cda34023b82897e28eb31f64fdda885c9fb542fb) by [@farrokhi](https://github.com/farrokhi)). +- Add tests ([1c9d163](https://github.com/farrokhi/dnsdiag/commit/1c9d16375942b1ca9bf9c171e7352edbbd030394) by [@farrokhi](https://github.com/farrokhi)). + +### Fixed + +- fix: default to AF_UNSPEC for automatic IPv4/IPv6 selection ([46f6235](https://github.com/farrokhi/dnsdiag/commit/46f623534394a9d9c8714e8252945b2b92bea0af) by [@farrokhi](https://github.com/farrokhi)). +- fix: correct DoH3 feature detection to check HTTPVersion.H3 ([7cfe3e9](https://github.com/farrokhi/dnsdiag/commit/7cfe3e940eadbb902e081a2a407e57e3237c1d52) by [@farrokhi](https://github.com/farrokhi)). +- Fix broken test when run from parent directory ([75903c6](https://github.com/farrokhi/dnsdiag/commit/75903c65def8b882e06be9f60cd9ddc580bf8a27) by [@farrokhi](https://github.com/farrokhi)). +- Fixed cookie display in dnsping ([455344d](https://github.com/farrokhi/dnsdiag/commit/455344ddf21e6b31a8f4ea8c1dbd311a8cd8a763) by [@farrokhi](https://github.com/farrokhi)). +- Fix: Only build packages when a new tag is pushed ([a2927e4](https://github.com/farrokhi/dnsdiag/commit/a2927e488dfde287e423aed625835fd027060241) by [@farrokhi](https://github.com/farrokhi)). +- Fix JSON Output Type Consistency ([af88b1b](https://github.com/farrokhi/dnsdiag/commit/af88b1b35d7c609c954c15a63567c9e9622806ad) by [@farrokhi](https://github.com/farrokhi)). +- Fix for IPv6 hostname resolution ([3f60d84](https://github.com/farrokhi/dnsdiag/commit/3f60d84cf42e44a645641091894434e22032c9af) by [@farrokhi](https://github.com/farrokhi)). +- Fix doh http version (#141) ([0ae5e93](https://github.com/farrokhi/dnsdiag/commit/0ae5e9388ffd028610a337d195cdbde32e1b7aa3) by [@farrokhi](https://github.com/farrokhi)). +- Fix formatting ([5801d7e](https://github.com/farrokhi/dnsdiag/commit/5801d7e1a09d812fb553a9dc8eb2070b60893dd3) by [@farrokhi](https://github.com/farrokhi)). + +### Removed + +- remove unnecessary files ([9e10740](https://github.com/farrokhi/dnsdiag/commit/9e10740c636f479f06a407f45c37c7a359c554c4) by [@farrokhi](https://github.com/farrokhi)). +- Remove stale email address ([99fd2fb](https://github.com/farrokhi/dnsdiag/commit/99fd2fbd0c137b5be26db06981121d86f6b4ab57) by [@farrokhi](https://github.com/farrokhi)). +- Remove unnecessary tests ([ff2b768](https://github.com/farrokhi/dnsdiag/commit/ff2b7685de66d29ea8c94ea411e4fa9d06e5caef) by [@farrokhi](https://github.com/farrokhi)). + +## [v2.8.1](https://github.com/farrokhi/dnsdiag/releases/tag/v2.8.1) - 2025-10-04 + +<small>[Compare with v2.8.0](https://github.com/farrokhi/dnsdiag/compare/v2.8.0...v2.8.1)</small> + +### Added + +- Add support for DNS cookies through --cookie (Fixes #120) ([1bbe224](https://github.com/farrokhi/dnsdiag/commit/1bbe2240803ce4b696219ab744a1b592ef9c7010) by [@farrokhi](https://github.com/farrokhi)). + +### Fixed + +- Fix duplicate CLI parameter ([bdb88f6](https://github.com/farrokhi/dnsdiag/commit/bdb88f6c4e965530e62243b4cb08ac9e526737c1) by [@farrokhi](https://github.com/farrokhi)). +- Fix DoT/DoQ lookup when passing hostname instead of IP address ([dcc0bfd](https://github.com/farrokhi/dnsdiag/commit/dcc0bfd60fe927322777e6142899e463822b4947) by [@farrokhi](https://github.com/farrokhi)). +- Fix DNS hostname support for encrypted protocols (DoH/HTTP3) ([6dc0bf5](https://github.com/farrokhi/dnsdiag/commit/6dc0bf51676e30cd606962d6b0a6c68cafcb04ea) by [@farrokhi](https://github.com/farrokhi)). +- Fix displaying ECS payload - add missing request size ([2d788e7](https://github.com/farrokhi/dnsdiag/commit/2d788e72816770b442f9a865e39dc15635827b6a) by [@farrokhi](https://github.com/farrokhi)). + +## [v2.8.0](https://github.com/farrokhi/dnsdiag/releases/tag/v2.8.0) - 2025-09-29 + +<small>[Compare with first commit](https://github.com/farrokhi/dnsdiag/compare/039fb2107d21f704860f6ebf96956d478b48a1fb...v2.8.0)</small> + +### Added + +- Add ECS examples to documentation ([8648262](https://github.com/farrokhi/dnsdiag/commit/8648262008d2ba682aaa7a9db4da4b2754d0c8ec) by [@farrokhi](https://github.com/farrokhi)). +- Add DoQ and DoH3 protocol support to dnstraceroute (#131) ([50dedb7](https://github.com/farrokhi/dnsdiag/commit/50dedb77b97e8593484525c43cd36567b7aa73ee) by [@farrokhi](https://github.com/farrokhi)). +- Add --ecs option (Fixes #110) (#128) ([aa50aa7](https://github.com/farrokhi/dnsdiag/commit/aa50aa738f41aac07204818b8fd747d7586bb0ca) by [@farrokhi](https://github.com/farrokhi)). +- Add `uv` examples ([d66d4bd](https://github.com/farrokhi/dnsdiag/commit/d66d4bdaf7f7556afb3241083e87643255d2d2af) by [@farrokhi](https://github.com/farrokhi)). +- Add help message that explains `--venv` parameter ([9fd73ec](https://github.com/farrokhi/dnsdiag/commit/9fd73ec501fa12d1c945ff072c7da72068699be1) by [@farrokhi](https://github.com/farrokhi)). +- Add missing -q to help message ([14dbce7](https://github.com/farrokhi/dnsdiag/commit/14dbce7bb575b64ea28c4af6faaae127a9347d0e) by [@farrokhi](https://github.com/farrokhi)). +- Add NextDNS and DNS4EU ([820b011](https://github.com/farrokhi/dnsdiag/commit/820b011d3a40609bad7fe32d51681458dc294329) by [@farrokhi](https://github.com/farrokhi)). +- Add support for DNS over QUIC (DoQ) protocol (#118) ([d14cfc3](https://github.com/farrokhi/dnsdiag/commit/d14cfc3bfedc25a22565c4ca1e84f8d3b2c26a9c) by [@farrokhi](https://github.com/farrokhi)). +- Add downloads/month badge ([cf8d53d](https://github.com/farrokhi/dnsdiag/commit/cf8d53d647cc6114b5669f716685fea20caf88f3) by [@farrokhi](https://github.com/farrokhi)). +- Add Wikimedia DNS resolver ([3623af3](https://github.com/farrokhi/dnsdiag/commit/3623af343663283eff9a5d23e028d6a970de5c5d) by [@farrokhi](https://github.com/farrokhi)). +- Add `-a` and `--answer` to display the first matching response (rdata) ([b321feb](https://github.com/farrokhi/dnsdiag/commit/b321feb7fcb1a2bd5f4f0d6620d73fa518c5fe5a) by [@farrokhi](https://github.com/farrokhi)). +- Add `-x` and `--expert` to display extra information ([7292af2](https://github.com/farrokhi/dnsdiag/commit/7292af27f17e406df069112b12d8535f68763f1f) by [@farrokhi](https://github.com/farrokhi)). +- Add `-T` and `--ttl` to display response TTL, if available ([a7f4ef1](https://github.com/farrokhi/dnsdiag/commit/a7f4ef1310e21f03eb0d146cd2180dc14b3681e0) by [@farrokhi](https://github.com/farrokhi)). +- Add support to override the default RR Class (fixes #114) ([f2fbc5d](https://github.com/farrokhi/dnsdiag/commit/f2fbc5d03570540d8ec13ce1ebfcb80b0e96ed33) by [@farrokhi](https://github.com/farrokhi)). +- Add new resolvers ([939ee86](https://github.com/farrokhi/dnsdiag/commit/939ee86e8eb9659973fad7ecd35e4c28324c3346) by [@farrokhi](https://github.com/farrokhi)). +- Add EDE support through `--ede` (Fixes #112) ([5609c58](https://github.com/farrokhi/dnsdiag/commit/5609c58d37fefb75d7443a9293661c849f2ecab7) by [@farrokhi](https://github.com/farrokhi)). +- Add --nsid to support RFC5001 NSID bit support ([c0c39f7](https://github.com/farrokhi/dnsdiag/commit/c0c39f7c33695ced2b4474efd01f538c960883f7) by [@farrokhi](https://github.com/farrokhi)). +- Add basic package builder logic ([2b5b3c7](https://github.com/farrokhi/dnsdiag/commit/2b5b3c7d405957b4e4a929a98ca62d940bdcd7e0) by [@farrokhi](https://github.com/farrokhi)). +- Add initial github actions config ([437ae45](https://github.com/farrokhi/dnsdiag/commit/437ae45a08fc128b42ad7d61a62286fc8a6c6f67) by [@farrokhi](https://github.com/farrokhi)). +- Add support for disabling recursion (-r) ([41cb7fa](https://github.com/farrokhi/dnsdiag/commit/41cb7fa403e45ece253fb8ec13c8e29d846bec9b) by [@farrokhi](https://github.com/farrokhi)). +- Add support for "-m" for cache-miss (Fixes #92) ([5cb3424](https://github.com/farrokhi/dnsdiag/commit/5cb34249944a1dd1ea6007d1f797ee00757d8232) by [@farrokhi](https://github.com/farrokhi)). +- Add support for sub-second intervals ([78a83fa](https://github.com/farrokhi/dnsdiag/commit/78a83fa3af2828598c9d70c603a6ec61f9bdab6b) by [@farrokhi](https://github.com/farrokhi)). +- Add PyPi counter badge ([5ee6422](https://github.com/farrokhi/dnsdiag/commit/5ee6422f95bffa787bd47ca0ed38be2b184e620b) by [@farrokhi](https://github.com/farrokhi)). +- Add cross platform package builder (#80) ([d677791](https://github.com/farrokhi/dnsdiag/commit/d6777917502c4c2674bb01cbfbb5c2863e57aa49) by [@farrokhi](https://github.com/farrokhi)). +- Add dnssec support to dnseval (#76) ([07c4a7d](https://github.com/farrokhi/dnsdiag/commit/07c4a7d324b9e08d2f20807be6c9d26b9a2c5121) by [@farrokhi](https://github.com/farrokhi)). +- Add Python 3.8 ([aede714](https://github.com/farrokhi/dnsdiag/commit/aede7146667591b73d4b02ca415454f1ad7981dd) by [@farrokhi](https://github.com/farrokhi)). +- Add docker badge ([aa58b5a](https://github.com/farrokhi/dnsdiag/commit/aa58b5a524847eb505d1f97923d911de96d8f920) by [@farrokhi](https://github.com/farrokhi)). +- Add Comodo and Verisign public DNS servers (#66) ([05485a9](https://github.com/farrokhi/dnsdiag/commit/05485a9db6aa413f68881fb1ddd436f10e79b662) by Brie Carranza). +- Add tox.ini ([9b0e1ac](https://github.com/farrokhi/dnsdiag/commit/9b0e1accbf896fead294c849a62b03f782949312) by [@farrokhi](https://github.com/farrokhi)). +- Add support for saving output to JSON ([1a7b467](https://github.com/farrokhi/dnsdiag/commit/1a7b467730f59ed92fed0e4c80f345614f12a80c) by Brie Carranza). +- Add -c0 support for infinite loop (fixes #57) ([3268fff](https://github.com/farrokhi/dnsdiag/commit/3268fffc0aedab1ec6f1518aa769455277d830f7) by [@farrokhi](https://github.com/farrokhi)). +- Add 3.8-dev target to test ([e54119c](https://github.com/farrokhi/dnsdiag/commit/e54119c7e8fc00631eba059ee4a04d6d8567e3c7) by [@farrokhi](https://github.com/farrokhi)). +- Add build-matrix support ([a4e250e](https://github.com/farrokhi/dnsdiag/commit/a4e250ec187035046b9fc87cff7dd769baf24434) by [@farrokhi](https://github.com/farrokhi)). +- Add license scan report and status ([1beb5ee](https://github.com/farrokhi/dnsdiag/commit/1beb5ee513dc2ec31ce0ca6ec6f532c5a248c113) by fossabot). +- Add sample input file with IPv4 address of public resolvers ([35a116d](https://github.com/farrokhi/dnsdiag/commit/35a116d65ec000b9071357e4d62077ef5b873a7d) by [@farrokhi](https://github.com/farrokhi)). +- Add CloudFlare's new resolver (v4/v6) (Fixes #51) ([f0a9cfb](https://github.com/farrokhi/dnsdiag/commit/f0a9cfb7d81f1e3a4f6bb47a6b2c805816345952) by [@farrokhi](https://github.com/farrokhi)). +- Add `-m` to force cache-miss measurement in dnseval (Closes #41) ([2a05c54](https://github.com/farrokhi/dnsdiag/commit/2a05c547eb607acdabc5c8da5f17a1959af4b8df) by [@farrokhi](https://github.com/farrokhi)). +- Add color mode to dnseval ("-C" option) ([ea07cee](https://github.com/farrokhi/dnsdiag/commit/ea07cee12a17cc8a188f7580704b37920503d2ec) by [@farrokhi](https://github.com/farrokhi)). +- Add verbose mode to print actual response(s) (FIX #28) ([79e0e86](https://github.com/farrokhi/dnsdiag/commit/79e0e86046c2b5c3c6c1ad0c5c6e6fe0c00716bb) by [@farrokhi](https://github.com/farrokhi)). +- Add option to pause between each dnsping request ([4c4e890](https://github.com/farrokhi/dnsdiag/commit/4c4e8909d08316bf7e5d8c9b3646673ceeaff253) by Hamish Coleman). +- Add EDNS0 support and update docs ([e7b21cf](https://github.com/farrokhi/dnsdiag/commit/e7b21cf0874754072873caf441ac56e93bc79616) by [@farrokhi](https://github.com/farrokhi)). +- Add support for EDNS0 flag ([118f84e](https://github.com/farrokhi/dnsdiag/commit/118f84ee6609ff2db6e3e537ae48abe23752b940) by [@farrokhi](https://github.com/farrokhi)). +- Add list of root servers as example for dnseval ([b1e45e7](https://github.com/farrokhi/dnsdiag/commit/b1e45e728bd2671fa5af2556b153228d0e61ac79) by [@farrokhi](https://github.com/farrokhi)). +- Add --tcp/-T option (fix #19) ([660954f](https://github.com/farrokhi/dnsdiag/commit/660954f8268b2e3f8109fcc0428862f8a30e9930) by [@farrokhi](https://github.com/farrokhi)). +- Add original dnspython as submodule ([efc1455](https://github.com/farrokhi/dnsdiag/commit/efc14554920a34bb7d57b14a1c7fe620f7279ffa) by [@farrokhi](https://github.com/farrokhi)). +- Add relevant category ([44e0389](https://github.com/farrokhi/dnsdiag/commit/44e0389cd61ca1993b702a716815accf81f3fe39) by [@farrokhi](https://github.com/farrokhi)). +- Add requirements.txt, now we depend on dnspython ([3157250](https://github.com/farrokhi/dnsdiag/commit/31572502878ef5e315a3526ad378da030e2debe9) by [@farrokhi](https://github.com/farrokhi)). +- add initial dnsdiag.py tool - the DNS diagnostics swiss army knife ([4d19e4a](https://github.com/farrokhi/dnsdiag/commit/4d19e4aadce3b8811f349c0175622a1f3dced026) by [@farrokhi](https://github.com/farrokhi)). +- add flags in dnseval output and update docs (close #13) ([9ae9c59](https://github.com/farrokhi/dnsdiag/commit/9ae9c594a80532dfefdd9efbd9cc895dcd26516d) by [@farrokhi](https://github.com/farrokhi)). +- add -4 and -6 to enforce network layer protocol (closes #9) ([423c59d](https://github.com/farrokhi/dnsdiag/commit/423c59d5c408e0c0cb0900d4581dd2f2ec385265) by [@farrokhi](https://github.com/farrokhi)). +- add possibility of using TCP instead of UDP ([c9b9e71](https://github.com/farrokhi/dnsdiag/commit/c9b9e71723a77d9196843a803db8695f7daf31ad) by [@farrokhi](https://github.com/farrokhi)). +- add basic unit test for nose ([17849ed](https://github.com/farrokhi/dnsdiag/commit/17849edb669650c2554eb1e396c858482a1425b5) by [@farrokhi](https://github.com/farrokhi)). +- add some badges of honor! ([e52b85d](https://github.com/farrokhi/dnsdiag/commit/e52b85d2c6f607aaf5b25a0a19ef6f8e08867fea) by [@farrokhi](https://github.com/farrokhi)). +- add expert hint and colorful mode ([9da2ccf](https://github.com/farrokhi/dnsdiag/commit/9da2ccf7ebfe98aed8e28fd492d587445220a55a) by [@farrokhi](https://github.com/farrokhi)). +- add installation instructions ([c6acf0d](https://github.com/farrokhi/dnsdiag/commit/c6acf0d1c57c911354127507a68e08e7efc4dc57) by [@farrokhi](https://github.com/farrokhi)). +- add link to github ([507fb62](https://github.com/farrokhi/dnsdiag/commit/507fb625adcc88f675f9dcd82fa9843b6a9c6167) by [@farrokhi](https://github.com/farrokhi)). +- add build status from travis ([2929637](https://github.com/farrokhi/dnsdiag/commit/2929637bc05ba84a478540d1f2142268dd1a9787) by [@farrokhi](https://github.com/farrokhi)). +- add travis-ci support ([b7f7772](https://github.com/farrokhi/dnsdiag/commit/b7f777221b415dde73dce3af73ab88da64798fa6) by [@farrokhi](https://github.com/farrokhi)). +- add setuptools support ([f82879b](https://github.com/farrokhi/dnsdiag/commit/f82879bf70dd7d6f9569cf32a9e2af88efe60029) by [@farrokhi](https://github.com/farrokhi)). +- add ability to define arbitrary src port and IP address ([6505d5f](https://github.com/farrokhi/dnsdiag/commit/6505d5fe1a9ebbc665cffb048bd441ea9508f272) by [@farrokhi](https://github.com/farrokhi)). +- add "-n" option to disable reverse lookups ([5d405b4](https://github.com/farrokhi/dnsdiag/commit/5d405b45eb8e612048550686b6fe85a0126e08fc) by [@farrokhi](https://github.com/farrokhi)). +- add option to use arbitrary DNS port number (default 53) ([b25735d](https://github.com/farrokhi/dnsdiag/commit/b25735d7e7e475279898620299422189df18051b) by [@farrokhi](https://github.com/farrokhi)). +- add Credits section ([539278d](https://github.com/farrokhi/dnsdiag/commit/539278d55d9d01a1400b761f380bbc737da44ef2) by [@farrokhi](https://github.com/farrokhi)). +- add support for AS Number and name in trace (fix #7) ([9752234](https://github.com/farrokhi/dnsdiag/commit/97522347b70b989885f206bfc52db6f0b0695aab) by [@farrokhi](https://github.com/farrokhi)). +- add initial version of dnstraceroute utility ([8bd7977](https://github.com/farrokhi/dnsdiag/commit/8bd79771dd18227013ac1f416f9b0ae95404ee1e) by [@farrokhi](https://github.com/farrokhi)). +- add opendns to sample file ([f84053d](https://github.com/farrokhi/dnsdiag/commit/f84053d73f74bf8690792e4a41cea93a6aee90de) by [@farrokhi](https://github.com/farrokhi)). +- add dnsperf.list sample file ([f3b8745](https://github.com/farrokhi/dnsdiag/commit/f3b8745e23fba56d5ef6aa5c92c7d7225a05c47f) by [@farrokhi](https://github.com/farrokhi)). +- add examples ([8195004](https://github.com/farrokhi/dnsdiag/commit/81950042bf8bd27fdc9004450da265dff8a804f2) by [@farrokhi](https://github.com/farrokhi)). + +### Fixed + +- Fix inconsistent help message ([ee25d18](https://github.com/farrokhi/dnsdiag/commit/ee25d18bb9cb1e275d203657651cbb9fc27f1003) by [@farrokhi](https://github.com/farrokhi)). +- Fix inconsistent command line parameters ([12698a8](https://github.com/farrokhi/dnsdiag/commit/12698a85b98e4c1629400e3d00a63bcb074b1516) by [@farrokhi](https://github.com/farrokhi)). +- Fix inconsistent CLI parameters ([17371d4](https://github.com/farrokhi/dnsdiag/commit/17371d4b8f8d13ad7cbc06079858dda0b2fe5cd4) by [@farrokhi](https://github.com/farrokhi)). +- Fix alignment ([08d379f](https://github.com/farrokhi/dnsdiag/commit/08d379fd3a5eb59f8fec0fe1ef6af620e5a631f0) by [@farrokhi](https://github.com/farrokhi)). +- Fix RTT display (broken in a recent commit) ([6bf8fc2](https://github.com/farrokhi/dnsdiag/commit/6bf8fc2a80fa72f6988ae8758ab8f2a3eb24bae8) by [@farrokhi](https://github.com/farrokhi)). +- Fix missing `-p` parameter (Fixes #106) ([099552f](https://github.com/farrokhi/dnsdiag/commit/099552f55b2fa52bda9355bd1a95ddf22b46c961) by [@farrokhi](https://github.com/farrokhi)). +- Fix version extraction during build ([55b29bf](https://github.com/farrokhi/dnsdiag/commit/55b29bf2e381f1436c981b68bb1498728eeefc66) by [@farrokhi](https://github.com/farrokhi)). +- fix: disable orange in non-colored mode" (#93) ([c1dbde2](https://github.com/farrokhi/dnsdiag/commit/c1dbde2c4ea3cb1ae5331ae7da0ee7c4cda90e45) by xhdix). +- Fix incorrect double-dash flag to enable "cache-miss" for dnseval (#91) ([3f8f629](https://github.com/farrokhi/dnsdiag/commit/3f8f629ec5aa95b4b797d05bc282e784ebd7b929) by Oscar Busk). +- Fix dependency version ([57bc745](https://github.com/farrokhi/dnsdiag/commit/57bc745dd7cc9c27b0d8174bf052a03c15ecc9ac) by [@farrokhi](https://github.com/farrokhi)). +- Fix docker badge ([c1807e3](https://github.com/farrokhi/dnsdiag/commit/c1807e3b10031e0e5b81b7f28ed8d7664789c49d) by [@farrokhi](https://github.com/farrokhi)). +- Fix link to article ([2d3069d](https://github.com/farrokhi/dnsdiag/commit/2d3069d80a2f63651817660b5d33b54054a1e5f5) by [@farrokhi](https://github.com/farrokhi)). +- Fix statistics calculation (Fix #64) ([7af735b](https://github.com/farrokhi/dnsdiag/commit/7af735b22be68f1d54094084f930f78eb0c3957e) by Babak Farrokhi). +- Fix travis config to build 3.7 and 3.8-dev ([814da79](https://github.com/farrokhi/dnsdiag/commit/814da79cb2c85df4a26fed72d200311a9f377912) by [@farrokhi](https://github.com/farrokhi)). +- Fixing 3.7 build again ([3f1325f](https://github.com/farrokhi/dnsdiag/commit/3f1325fafd3bdfec4fbe6459cf186256c9a2d6e1) by [@farrokhi](https://github.com/farrokhi)). +- Fix badges ([3037784](https://github.com/farrokhi/dnsdiag/commit/303778475e3a30b3e0d6215208ceb75dd4a8d059) by [@farrokhi](https://github.com/farrokhi)). +- Fix sample input filename in README ([8b9bf4f](https://github.com/farrokhi/dnsdiag/commit/8b9bf4feeb55205fabda440b3654ac300a1c2b86) by [@farrokhi](https://github.com/farrokhi)). +- Fix setuptools ([86d4a19](https://github.com/farrokhi/dnsdiag/commit/86d4a1932ff6844be7bf2b5a14302e7f241f43ae) by [@farrokhi](https://github.com/farrokhi)). +- Fix setuptool installation and dependecies ([51641d7](https://github.com/farrokhi/dnsdiag/commit/51641d7367b2460fe31da544c76eaeb8b7b69782) by [@farrokhi](https://github.com/farrokhi)). +- Fix display in case of no answer (fix #34) ([dd2899c](https://github.com/farrokhi/dnsdiag/commit/dd2899c3497cb3876bd225009edf61568b0ae314) by [@farrokhi](https://github.com/farrokhi)). +- Fix string formatting ([233898a](https://github.com/farrokhi/dnsdiag/commit/233898a4a25af2af0059f4d6c04a9a9dadc1aa8f) by [@farrokhi](https://github.com/farrokhi)). +- Fix build with Travis CI ([6704180](https://github.com/farrokhi/dnsdiag/commit/6704180df5e7424a9c84f17245040b8228a00202) by [@farrokhi](https://github.com/farrokhi)). +- Fix handling invalid TTL and some output string justifications (fix #26, #27) ([cf3cfcc](https://github.com/farrokhi/dnsdiag/commit/cf3cfcc49395a4a560e099b39dacf7c08295f1c9) by [@farrokhi](https://github.com/farrokhi)). +- Fix conflicting -e switch (--expert and --edns). ([e0bed3c](https://github.com/farrokhi/dnsdiag/commit/e0bed3c07f97bc6298eaa624c2521d299b204e63) by [@farrokhi](https://github.com/farrokhi)). +- Fix looking up NS record from root server ([6779dc0](https://github.com/farrokhi/dnsdiag/commit/6779dc0b9d7972b3ff3814f058ec6ba95dde631d) by [@farrokhi](https://github.com/farrokhi)). +- Fix bug in dealing with root servers ([fe78505](https://github.com/farrokhi/dnsdiag/commit/fe785056373b3b2a8c0add450f2e4da6897e0887) by [@farrokhi](https://github.com/farrokhi)). +- Fix text alignment ([b779440](https://github.com/farrokhi/dnsdiag/commit/b779440a1ede2d6d8436ef3dea5aa6ca1ade2d6f) by [@farrokhi](https://github.com/farrokhi)). +- fix long arguments ([627e53f](https://github.com/farrokhi/dnsdiag/commit/627e53f1a858ee1fd700eb0be52e9a804e076972) by [@farrokhi](https://github.com/farrokhi)). +- fix README and code cleanup ([4dd5065](https://github.com/farrokhi/dnsdiag/commit/4dd5065c73b954f4f51378b22fd77cde947bcfde) by [@farrokhi](https://github.com/farrokhi)). +- fix NoAnswer error when RRSIG requested (fix #14) ([1cc5a38](https://github.com/farrokhi/dnsdiag/commit/1cc5a38a4b4f05a9eebc5ac046bba8825039478d) by [@farrokhi](https://github.com/farrokhi)). +- fix script names for setuptools ([846d980](https://github.com/farrokhi/dnsdiag/commit/846d980a09dc70da2a6193e53f0e8ae47dd81aa3) by [@farrokhi](https://github.com/farrokhi)). +- fix crash when resolving dns hostname to IP (close #9) ([848ea0f](https://github.com/farrokhi/dnsdiag/commit/848ea0f34cf33c44d8d5802e3f81b5d9ff33e8de) by [@farrokhi](https://github.com/farrokhi)). +- fix variable name after recent refactoring ([0b512b5](https://github.com/farrokhi/dnsdiag/commit/0b512b537a0065996f065c65f1874d312053d37b) by [@farrokhi](https://github.com/farrokhi)). +- fix stddev calculaction logic ([c754115](https://github.com/farrokhi/dnsdiag/commit/c7541154c050cb28034ce215dac500e12dcaae02) by [@farrokhi](https://github.com/farrokhi)). +- fix a calculation bug with "-c1" (closes #10) ([ca49f66](https://github.com/farrokhi/dnsdiag/commit/ca49f667809e1f32b82594b19f5a9cfca34417c1) by [@farrokhi](https://github.com/farrokhi)). +- fix typo ([3ea3434](https://github.com/farrokhi/dnsdiag/commit/3ea343467d593016f1f409f7e37656e7160067a0) by [@farrokhi](https://github.com/farrokhi)). +- fix markdown spacing ([1ce9d41](https://github.com/farrokhi/dnsdiag/commit/1ce9d41672c99bf08de8e1ed3dd2e0eef378d0dd) by [@farrokhi](https://github.com/farrokhi)). +- fix cymruwhois dependency for setuptools ([986871a](https://github.com/farrokhi/dnsdiag/commit/986871a5b918d7a69a9853ede55e0254de6119f0) by [@farrokhi](https://github.com/farrokhi)). +- fixed dependecy mismatch ([8a5b84a](https://github.com/farrokhi/dnsdiag/commit/8a5b84adb084194e1c0143bacecba97ab7a985da) by [@farrokhi](https://github.com/farrokhi)). +- fix signal issue in Windows ([026d127](https://github.com/farrokhi/dnsdiag/commit/026d12730d0f87dd8fe320681fd8a030e033bf3a) by [@farrokhi](https://github.com/farrokhi)). +- fix signal handling error on windows ([8b40cea](https://github.com/farrokhi/dnsdiag/commit/8b40cea4a9fa66870c609130ffeec0d0935d5be3) by [@farrokhi](https://github.com/farrokhi)). +- fix links ([d8ce420](https://github.com/farrokhi/dnsdiag/commit/d8ce420686557c663894746436a5a1751d416265) by [@farrokhi](https://github.com/farrokhi)). +- fix layout with variable len addresses (close #4) ([d18925b](https://github.com/farrokhi/dnsdiag/commit/d18925b1e3baf852ef0959d2acef45dfb6d480d9) by [@farrokhi](https://github.com/farrokhi)). +- fixed line-wrapping in text files ([e104136](https://github.com/farrokhi/dnsdiag/commit/e104136c15ba7de8d5bf6def2fa4f69d354ebab9) by [@farrokhi](https://github.com/farrokhi)). +- fix syntax ([6ea6f7e](https://github.com/farrokhi/dnsdiag/commit/6ea6f7e0cf4d40f1fddd6953f69e881fd997b10b) by [@farrokhi](https://github.com/farrokhi)). +- fix arbitrary dns server assignment bug ([251703c](https://github.com/farrokhi/dnsdiag/commit/251703c0be0af345f648201c4060536be26e2b49) by [@farrokhi](https://github.com/farrokhi)). + +### Changed + +- Change EDNS buffer size to 1232 to avoid fragmentation (Fixes #111) ([424f828](https://github.com/farrokhi/dnsdiag/commit/424f828a7f5996e868dfba138321ed846388789a) by [@farrokhi](https://github.com/farrokhi)). +- Change default behavior of --edns to disabled by default (Fixes #97) (#99) ([4d6512d](https://github.com/farrokhi/dnsdiag/commit/4d6512d0d4b91da111ee09fffeeea3fac33a0f42) by [@farrokhi](https://github.com/farrokhi)). +- Change default ping interval to 1 second ([a1f9c65](https://github.com/farrokhi/dnsdiag/commit/a1f9c65bbee439c9309f4339c744ece436d319d7) by [@farrokhi](https://github.com/farrokhi)). +- Change default timeout value to 2 (was 5) (fix #24) ([89c0db0](https://github.com/farrokhi/dnsdiag/commit/89c0db04a603ba61982143887ccdb0910d0e6a57) by [@farrokhi](https://github.com/farrokhi)). +- Change separator line ([6ed1068](https://github.com/farrokhi/dnsdiag/commit/6ed1068241730a9c634e5a23fe683637c000d2f4) by [@farrokhi](https://github.com/farrokhi)). + +### Removed + +- Remove pypy from build ([a6abfbb](https://github.com/farrokhi/dnsdiag/commit/a6abfbbe3be211ff87d216b31d125f0c44c5b00f) by [@farrokhi](https://github.com/farrokhi)). +- Remove funding file ([71bc51a](https://github.com/farrokhi/dnsdiag/commit/71bc51ae75047edcbedd7de24e092ddc0ebcd0cf) by [@farrokhi](https://github.com/farrokhi)). +- Remove artifact ([1825ce6](https://github.com/farrokhi/dnsdiag/commit/1825ce6519628d248d7ce14f02002e907c590f93) by [@farrokhi](https://github.com/farrokhi)). +- Remove unneeded badges ([b532394](https://github.com/farrokhi/dnsdiag/commit/b5323940b7a34b4b4216ee248b5a2902ccba39af) by [@farrokhi](https://github.com/farrokhi)). +- Remove older python ([53b9ce1](https://github.com/farrokhi/dnsdiag/commit/53b9ce1cd98d366d318899a22391e632cc49a433) by [@farrokhi](https://github.com/farrokhi)). +- Remove a leftover debug message ([0d65361](https://github.com/farrokhi/dnsdiag/commit/0d65361f46415a70781e0f898aa8cf1996ad42c2) by [@farrokhi](https://github.com/farrokhi)). +- Remove local dnspython submodule since the latest dnspython (as of 1.15.0) supports all the requirements ([f1c3e76](https://github.com/farrokhi/dnsdiag/commit/f1c3e76b8c042c7c0702b9bf76e331bf0fd8d618) by [@farrokhi](https://github.com/farrokhi)). +- Remove -e from examples ([ebf09d3](https://github.com/farrokhi/dnsdiag/commit/ebf09d3800f40edcf4ea7e34ea00afa20b2a98ec) by [@farrokhi](https://github.com/farrokhi)). +- Remove dnspython from external requirements ([e9f4625](https://github.com/farrokhi/dnsdiag/commit/e9f4625b86cb6e1b90228bae1e51fa702ea61a48) by [@farrokhi](https://github.com/farrokhi)). +- remove patched dnspython module and use stock version ([1a10ae0](https://github.com/farrokhi/dnsdiag/commit/1a10ae0ce986d959a43cd5ae91d05210543c174c) by [@farrokhi](https://github.com/farrokhi)). +- Remove AF ([f84388b](https://github.com/farrokhi/dnsdiag/commit/f84388be939b1dd57ca90672f22809f35dddc764) by [@farrokhi](https://github.com/farrokhi)). +- remove unnecessary option ([d568b3b](https://github.com/farrokhi/dnsdiag/commit/d568b3b57c99b85e0cc90f99ce6660f73e55ffe4) by [@farrokhi](https://github.com/farrokhi)). + +## [v2.9.3](https://github.com/farrokhi/dnsdiag/releases/tag/v2.9.3) - 2026-01-31 + +<small>[Compare with v2.9.2](https://github.com/farrokhi/dnsdiag/compare/v2.9.2...v2.9.3)</small> + +### Fixed + +- fix: remove Windows ARM64 from CI build matrix ([04f8b62](https://github.com/farrokhi/dnsdiag/commit/04f8b62)) by [@farrokhi](https://github.com/farrokhi)). Removed Windows ARM64 platform from build workflow and documentation due to cryptography dependency lacking pre-built wheels for this platform. +- fix: replace unreliable dnspython timing with perf_counter measurements ([0a3a5f6](https://github.com/farrokhi/dnsdiag/commit/0a3a5f6)) by [@farrokhi](https://github.com/farrokhi)). Improves response time accuracy across all DNS protocols. +- fix: improved error handling for DoH, DoH3 and DoQ ([6d14c1f](https://github.com/farrokhi/dnsdiag/commit/6d14c1f)) by [@farrokhi](https://github.com/farrokhi)). Better user-friendly error messages instead of Python stack traces for modern DNS protocols. +- fix: treat connection refused as transient across all DNS protocols ([099d627](https://github.com/farrokhi/dnsdiag/commit/099d627)) by [@farrokhi](https://github.com/farrokhi)). DoH, DoH3, and DoQ now continue pinging when connection is refused (like UDP/TCP), showing error messages and collecting packet loss statistics uniformly across all protocols. +- fix: handle transient QUIC connection failures gracefully ([87b2285](https://github.com/farrokhi/dnsdiag/commit/87b2285)) by [@farrokhi](https://github.com/farrokhi)). Treats UnexpectedEOF exceptions as transient failures that should be retried. +- fix: correctly detect Windows ARM64 architecture in build script ([6d36c8b](https://github.com/farrokhi/dnsdiag/commit/6d36c8b)) by [@farrokhi](https://github.com/farrokhi)). Uses MSYSTEM_CARCH environment variable on Windows. + ## [2.9.1](https://github.com/farrokhi/dnsdiag/releases/tag/2.9.1) - 2025-10-31 <small>[Compare with v2.9.0](https://github.com/farrokhi/dnsdiag/compare/v2.9.0...2.9.1)</small> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.9.2/README.md new/dnsdiag-2.9.3/README.md --- old/dnsdiag-2.9.2/README.md 2026-01-13 11:12:08.000000000 +0100 +++ new/dnsdiag-2.9.3/README.md 2026-02-03 18:18:21.000000000 +0100 @@ -81,6 +81,16 @@ From time to time, binary packages will be released for Windows, Mac OS X and Linux. You can grab the latest release from [releases page](https://github.com/farrokhi/dnsdiag/releases). +### Supported Platforms + +Pre-built binaries are available for: + +- Linux (x86_64, ARM64) +- macOS (Intel, Apple Silicon) +- Windows (x86_64) + +Windows ARM64 is not currently supported due to build dependencies requiring native compilation toolchains that are not readily available. If you're using Windows on ARM, you can run dnsdiag using Windows Subsystem for Linux (WSL2) or install directly from source. + ## Docker If you prefer not to install `dnsdiag` on your local machine, you can use the @@ -94,7 +104,7 @@ `dnsping` allows you to "ping" a DNS resolver by sending an arbitrary DNS query multiple times. For a full list of supported command-line options, use `--help`. Here are a few key flags: -- Use `--tcp`, `--tls`, `--doh`, `--quic` or `--http3` to select the transport protocol (default is UDP). +- Use `--tcp`, `--tls`, `--doh`, `--quic` or `--http3` to select the transport protocol (default is UDP). These options are mutually exclusive; only one protocol can be specified per command. - Use `--flags` to display response flags, including EDNS flags, for each response. - Use `--dnssec` to request DNSSEC validation, if available. - Extended DNS Error messages ([RFC 8914](https://www.rfc-editor.org/rfc/rfc8914)) are automatically displayed when present. @@ -176,6 +186,42 @@ min=24.794 ms, avg=27.673 ms, max=30.552 ms, stddev=4.072 ms ``` +## Interpreting DNSSEC and Security-Related Flags + +When using `--dnssec` and `--flags`, `dnsping` exposes DNS protocol fields that are +directly relevant to DNS security validation. These values indicate whether a +resolver is capable of validating DNSSEC and whether a response was successfully +verified. + +Common flags: + +- **DO (DNSSEC OK)** + Indicates that the client is requesting DNSSEC-related records. Its presence + shows that the resolver supports DNSSEC queries. + +- **AD (Authenticated Data)** + Set by validating resolvers when the response has been cryptographically + validated using DNSSEC. This is a strong signal that DNSSEC validation is active + and successful. + +Typical patterns: + +| Result | Meaning | +|-------|--------| +| `NOERROR` with `AD` flag | DNSSEC validation succeeded | +| `SERVFAIL` with `DO` flag | DNSSEC validation failed (often due to broken signatures or misconfiguration) | +| No `AD` flag present | Resolver is not performing DNSSEC validation | + +Extended DNS Errors (EDE, RFC 8914) provide additional diagnostic information when +DNSSEC validation fails. For example: + +- **EDE:10** – *DNSSEC Bogus* (invalid or broken DNSSEC data) +- **EDE:6** – *DNSSEC Signature Expired* +- **EDE:7** – *DNSSEC Signature Not Yet Valid* + +These indicators make `dnsping` useful not only for performance testing, but also +for validating whether resolvers correctly enforce DNSSEC and for diagnosing +DNSSEC deployment issues. # dnstraceroute @@ -183,7 +229,7 @@ destination. You may want to compare this with your actual network traceroute to ensure that your DNS traffic is not being routed through any unwanted paths. -`dnstraceroute` supports multiple transport protocols: +`dnstraceroute` supports multiple transport protocols (mutually exclusive): - UDP (default) - Traditional DNS queries - TCP (`--tcp`) - DNS over TCP - DoQ (`--quic`) - DNS over QUIC (supported by AdGuard DNS) @@ -226,7 +272,7 @@ You can use `dnseval` to evaluate response times across different transport protocols, including UDP (default), TCP, DoT (DNS over TLS), DoH (DNS over HTTPS), DoQ (DNS over QUIC), and DoH3 (DNS over HTTP/3) by using the `--tcp`, -`--tls`, `--doh`, `--quic`, and `--http3` flags, respectively. +`--tls`, `--doh`, `--quic`, and `--http3` flags, respectively. These protocol options are mutually exclusive; only one can be specified per command. ## Protocol Support Summary diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.9.2/build-pkgs.sh new/dnsdiag-2.9.3/build-pkgs.sh --- old/dnsdiag-2.9.2/build-pkgs.sh 2026-01-13 11:12:08.000000000 +0100 +++ new/dnsdiag-2.9.3/build-pkgs.sh 2026-02-03 18:18:21.000000000 +0100 @@ -43,7 +43,13 @@ else PLATFORM=$(uname -s | tr 'A-Z' 'a-z') fi -ARCH=$(uname -m) +# On Windows, use MSYSTEM_CARCH if set (correctly identifies ARM64) +# Otherwise fall back to uname -m (works correctly on Linux/macOS) +if [ "Windows_NT" = "${OS}" ] && [ -n "${MSYSTEM_CARCH}" ]; then + ARCH="${MSYSTEM_CARCH}" +else + ARCH=$(uname -m) +fi DDVER=$(grep __version__ dnsdiag/shared.py | awk -F\' '{print $2}') [ -z "${DDVER}" ] && die "Failed to extract version number from dnsdiag/shared.py" PKG_NAME="dnsdiag-${DDVER}.${PLATFORM}-${ARCH}-bin" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.9.2/dnsdiag/dns.py new/dnsdiag-2.9.3/dnsdiag/dns.py --- old/dnsdiag-2.9.2/dnsdiag/dns.py 2026-01-13 11:12:08.000000000 +0100 +++ new/dnsdiag-2.9.3/dnsdiag/dns.py 2026-02-03 18:18:21.000000000 +0100 @@ -24,9 +24,9 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import datetime import errno import socket +import time from statistics import stdev from typing import Optional, List, Any @@ -114,6 +114,15 @@ _TTL = socket_ttl dns.query.socket_factory = CustomSocket + # Also set QUIC socket factory if available + # dns.quic._sync.socket_factory is documented as "Can be overridden if needed in special situations" + try: + import dns.quic._sync as quic_sync + quic_sync.socket_factory = CustomSocket + except (ImportError, AttributeError): + # aioquic not installed or QUIC not available + pass + for i in range(count): if force_miss: @@ -131,6 +140,7 @@ query = dns.message.make_query(fqdn, rdtype, dns.rdataclass.IN, use_edns=False, want_dnssec=False) try: + stime = time.perf_counter() if proto == PROTO_UDP: response = dns.query.udp(query, server, timeout=timeout, port=dst_port, source=src_ip, ignore_unexpected=True) @@ -171,23 +181,25 @@ break except OSError as e: # Transient network errors should be re-raised for caller to handle + # Exception: during traceroute (socket_ttl set), these errors are expected if e.errno in (errno.EHOSTUNREACH, errno.ENETUNREACH): + if socket_ttl: + break raise elif socket_ttl: # other acceptable errors while doing traceroute break err(f"ERROR: {e.strerror}") raise OSError(e) except Exception as e: - err(f"ERROR: {e}") + # In traceroute mode, connection failures are expected + if socket_ttl: + break + err(f"ERROR: {type(e).__name__}: {e}") break else: - # convert time to milliseconds, considering that - # time property is retruned differently by query.https - # dns library returns float for most protocols but timedelta for HTTPS - if isinstance(response.time, datetime.timedelta): - elapsed = response.time.total_seconds() * 1000 - else: - elapsed = response.time * 1000 + etime = time.perf_counter() + # Use perf_counter() measurements for accurate wall-clock time + elapsed = (etime - stime) * 1000 # Convert seconds to milliseconds response_times.append(elapsed) if response: retval.response = response diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.9.2/dnsdiag/shared.py new/dnsdiag-2.9.3/dnsdiag/shared.py --- old/dnsdiag-2.9.2/dnsdiag/shared.py 2026-01-13 11:12:08.000000000 +0100 +++ new/dnsdiag-2.9.3/dnsdiag/shared.py 2026-02-03 18:18:21.000000000 +0100 @@ -27,8 +27,9 @@ import random import string import sys +from typing import Optional -__version__ = '2.9.2' +__version__ = '2.9.3' def random_string(min_length: int = 5, max_length: int = 10) -> str: @@ -46,6 +47,26 @@ print(s, file=sys.stderr, flush=True) +def set_protocol_exclusive(new_proto: int, current_option: str, proto_option_set: Optional[str]) -> tuple[int, str]: + """ + Set protocol ensuring mutual exclusivity. + + Args: + new_proto: Protocol constant to set + current_option: Current option being processed (e.g., "-T") + proto_option_set: Previously set protocol option or None + + Returns: + Tuple of (protocol, option_name) + + Raises: + SystemExit if a protocol was already set + """ + if proto_option_set is not None: + die(f"ERROR: cannot use {current_option} with {proto_option_set}") + return new_proto, current_option + + def unsupported_feature(feature: str = "") -> None: if feature: die(f"{feature} not available", exit_code=127) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.9.2/dnseval.py new/dnsdiag-2.9.3/dnseval.py --- old/dnsdiag-2.9.2/dnseval.py 2026-01-13 11:12:08.000000000 +0100 +++ new/dnsdiag-2.9.3/dnseval.py 2026-02-03 18:18:21.000000000 +0100 @@ -44,7 +44,7 @@ import dnsdiag.dns from dnsdiag.dns import PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_HTTPS, PROTO_QUIC, PROTO_HTTP3, flags_to_text, get_default_port -from dnsdiag.shared import __version__, Colors, valid_hostname, die, err +from dnsdiag.shared import __version__, Colors, valid_hostname, die, err, set_protocol_exclusive __author__ = 'Babak Farrokhi ([email protected])' __license__ = 'BSD' @@ -221,6 +221,7 @@ verbose = False color_mode = False warmup = True + proto_option_set: Optional[str] = None qname = 'wikipedia.org' try: @@ -266,7 +267,7 @@ elif o in ("-t", "--type"): rdatatype = a elif o in ("-T", "--tcp"): - proto = PROTO_TCP + proto, proto_option_set = set_protocol_exclusive(PROTO_TCP, o, proto_option_set) if use_default_dst_port: dst_port = get_default_port(proto) elif o in ("-S", "--srcip"): @@ -288,19 +289,19 @@ elif o in ("-v", "--verbose"): verbose = True elif o in ("-X", "--tls"): - proto = PROTO_TLS + proto, proto_option_set = set_protocol_exclusive(PROTO_TLS, o, proto_option_set) if use_default_dst_port: dst_port = get_default_port(proto) elif o in ("-H", "--doh"): - proto = PROTO_HTTPS + proto, proto_option_set = set_protocol_exclusive(PROTO_HTTPS, o, proto_option_set) if use_default_dst_port: dst_port = get_default_port(proto) elif o in ("-Q", "--quic"): - proto = PROTO_QUIC + proto, proto_option_set = set_protocol_exclusive(PROTO_QUIC, o, proto_option_set) if use_default_dst_port: dst_port = get_default_port(proto) elif o in ("-3", "--http3"): - proto = PROTO_HTTP3 + proto, proto_option_set = set_protocol_exclusive(PROTO_HTTP3, o, proto_option_set) if use_default_dst_port: dst_port = get_default_port(proto) elif o in ("-p", "--port"): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.9.2/dnsping.py new/dnsdiag-2.9.3/dnsping.py --- old/dnsdiag-2.9.2/dnsping.py 2026-01-13 11:12:08.000000000 +0100 +++ new/dnsdiag-2.9.3/dnsping.py 2026-02-03 18:18:21.000000000 +0100 @@ -25,13 +25,13 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import datetime import errno import getopt import ipaddress import os import signal import socket +import ssl import sys import time from statistics import stdev @@ -51,7 +51,8 @@ from dnsdiag.dns import PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_HTTPS, PROTO_QUIC, PROTO_HTTP3, proto_to_text, \ get_default_port, valid_rdatatype -from dnsdiag.shared import __version__, valid_hostname, unsupported_feature, random_string, die, err +from dnsdiag.shared import __version__, valid_hostname, unsupported_feature, random_string, die, err, \ + set_protocol_exclusive __author__ = 'Babak Farrokhi ([email protected])' __license__ = 'BSD' @@ -187,6 +188,7 @@ af = None af_ipv4_set = False af_ipv6_set = False + proto_option_set: Optional[str] = None qname = 'wikipedia.org' try: @@ -266,27 +268,27 @@ die(f"ERROR: invalid RR class: {a}") elif o in ("-T", "--tcp"): - proto = PROTO_TCP + proto, proto_option_set = set_protocol_exclusive(PROTO_TCP, o, proto_option_set) if use_default_dst_port: dst_port = get_default_port(proto) elif o in ("-X", "--tls"): - proto = PROTO_TLS + proto, proto_option_set = set_protocol_exclusive(PROTO_TLS, o, proto_option_set) if use_default_dst_port: dst_port = get_default_port(proto) elif o in ("-H", "--doh"): - proto = PROTO_HTTPS + proto, proto_option_set = set_protocol_exclusive(PROTO_HTTPS, o, proto_option_set) if use_default_dst_port: dst_port = get_default_port(proto) elif o in ("-Q", "--quic"): - proto = PROTO_QUIC + proto, proto_option_set = set_protocol_exclusive(PROTO_QUIC, o, proto_option_set) if use_default_dst_port: dst_port = get_default_port(proto) elif o in ("-3", "--http3"): - proto = PROTO_HTTP3 + proto, proto_option_set = set_protocol_exclusive(PROTO_HTTP3, o, proto_option_set) if use_default_dst_port: dst_port = get_default_port(proto) @@ -427,11 +429,30 @@ source=src_ip, source_port=src_port) elif proto is PROTO_TLS: if hasattr(dns.query, 'tls'): - # Use resolved IP for connection, but provide hostname for SNI/certificate validation - server_hostname = dnsserver_hostname if dnsserver_hostname != dnsserver_ip else None - answers = dns.query.tls(query, dnsserver_ip, timeout=timeout, port=dst_port, - source=src_ip, source_port=src_port, - server_hostname=server_hostname) + try: + # Use resolved IP for connection, but provide hostname for SNI/certificate validation + server_hostname = dnsserver_hostname if dnsserver_hostname != dnsserver_ip else None + answers = dns.query.tls(query, dnsserver_ip, timeout=timeout, port=dst_port, + source=src_ip, source_port=src_port, + server_hostname=server_hostname) + except dns.exception.Timeout: + if not quiet: + print("Request timeout", flush=True) + continue + except (ConnectionResetError, BrokenPipeError): + if not quiet: + print("Connection closed unexpectedly", flush=True) + continue + except socket.gaierror: + if not quiet: + print("Name resolution failed", flush=True) + continue + except ssl.SSLCertVerificationError as e: + die(f"Certificate verification failed: {e}") + except ssl.SSLError: + if not quiet: + print("Connection failed", flush=True) + continue else: unsupported_feature("DNS-over-TLS") @@ -449,7 +470,27 @@ except dns.query.NoDOH: die("ERROR: python httpx module not available") except httpx.ConnectError: - die(f"DoH connection failed on port {dst_port}") + if not quiet: + print("Connection refused", flush=True) + continue + except (ConnectionResetError, BrokenPipeError): + if not quiet: + print("Connection closed unexpectedly", flush=True) + continue + except socket.gaierror: + if not quiet: + print("Name resolution failed", flush=True) + continue + except (httpx.WriteTimeout, httpx.StreamError, httpx.ProtocolError): + if not quiet: + print("Connection failed", flush=True) + continue + except ssl.SSLCertVerificationError as e: + die(f"Certificate verification failed: {e}") + except ssl.SSLError: + if not quiet: + print("Connection failed", flush=True) + continue else: unsupported_feature("DNS-over-HTTPS (DoH)") @@ -465,7 +506,35 @@ source=src_ip, source_port=src_port, http_version=dns.query.HTTPVersion.H3) except ConnectionRefusedError: - die(f"DoH3 connection refused on port {dst_port}") + if not quiet: + print("Connection refused", flush=True) + continue + except (ConnectionResetError, BrokenPipeError): + if not quiet: + print("Connection closed unexpectedly", flush=True) + continue + except socket.gaierror: + if not quiet: + print("Name resolution failed", flush=True) + continue + except (httpx.WriteTimeout, httpx.StreamError, httpx.ProtocolError): + if not quiet: + print("Connection failed", flush=True) + continue + except ssl.SSLCertVerificationError as e: + die(f"Certificate verification failed: {e}") + except ssl.SSLError: + if not quiet: + print("Connection failed", flush=True) + continue + except Exception as e: + # Catch QUIC-specific exceptions (UnexpectedEOF, etc.) + if e.__class__.__name__ in ('UnexpectedEOF', 'QuicConnectionError', 'H3Error'): + if not quiet: + print("Connection closed unexpectedly", flush=True) + continue + else: + raise else: unsupported_feature("DNS-over-HTTPS/3 (DoH3)") @@ -478,9 +547,35 @@ source=src_ip, source_port=src_port, server_hostname=server_hostname) except dns.exception.Timeout: - die(f"DoQ connection timeout on port {dst_port}") + if not quiet: + print("Request timeout", flush=True) + continue except ConnectionRefusedError: - die(f"DoQ connection refused on port {dst_port}") + if not quiet: + print("Connection refused", flush=True) + continue + except (ConnectionResetError, BrokenPipeError): + if not quiet: + print("Connection closed unexpectedly", flush=True) + continue + except socket.gaierror: + if not quiet: + print("Name resolution failed", flush=True) + continue + except ssl.SSLCertVerificationError as e: + die(f"Certificate verification failed: {e}") + except ssl.SSLError: + if not quiet: + print("Connection failed", flush=True) + continue + except Exception as e: + # Catch QUIC-specific exceptions + if e.__class__.__name__ in ('UnexpectedEOF', 'QuicConnectionError', 'StreamFinishedError'): + if not quiet: + print("Connection closed unexpectedly", flush=True) + continue + else: + raise else: unsupported_feature("DNS-over-QUIC (DoQ)") @@ -525,13 +620,8 @@ shutdown = True break else: - # convert time to milliseconds, considering that - # time property is returned differently by query.https - # dns library returns float for most protocols but timedelta for HTTPS - if isinstance(answers.time, datetime.timedelta): - elapsed = answers.time.total_seconds() * 1000 - else: - elapsed = answers.time * 1000 + # Use perf_counter() measurements for accurate wall-clock time + elapsed = (etime - stime) * 1000 # Convert seconds to milliseconds response_time.append(elapsed) if not quiet: extras = "" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.9.2/dnstraceroute.py new/dnsdiag-2.9.3/dnstraceroute.py --- old/dnsdiag-2.9.2/dnstraceroute.py 2026-01-13 11:12:08.000000000 +0100 +++ new/dnsdiag-2.9.3/dnstraceroute.py 2026-02-03 18:18:21.000000000 +0100 @@ -42,7 +42,7 @@ import dnsdiag.whois from dnsdiag.dns import PROTO_UDP, PROTO_TCP, PROTO_QUIC, PROTO_HTTP3, get_default_port -from dnsdiag.shared import __version__, Colors, valid_hostname, die, err +from dnsdiag.shared import __version__, Colors, valid_hostname, die, err, set_protocol_exclusive # Global Variables quiet = False @@ -198,6 +198,7 @@ af = None # auto-detect from server address af_ipv4_set = False af_ipv6_set = False + proto_option_set: Optional[str] = None args = None try: @@ -261,15 +262,15 @@ elif o in "-n": should_resolve = False elif o in ("-T", "--tcp"): - proto = PROTO_TCP + proto, proto_option_set = set_protocol_exclusive(PROTO_TCP, o, proto_option_set) if use_default_dest_port: dest_port = get_default_port(proto) elif o in ("-Q", "--quic"): - proto = PROTO_QUIC + proto, proto_option_set = set_protocol_exclusive(PROTO_QUIC, o, proto_option_set) if use_default_dest_port: dest_port = get_default_port(proto) elif o in ("-3", "--http3"): - proto = PROTO_HTTP3 + proto, proto_option_set = set_protocol_exclusive(PROTO_HTTP3, o, proto_option_set) if use_default_dest_port: dest_port = get_default_port(proto) elif o in ("-4", "--ipv4"): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.9.2/pyproject.toml new/dnsdiag-2.9.3/pyproject.toml --- old/dnsdiag-2.9.2/pyproject.toml 2026-01-13 11:12:08.000000000 +0100 +++ new/dnsdiag-2.9.3/pyproject.toml 2026-02-03 18:18:21.000000000 +0100 @@ -4,7 +4,7 @@ [project] name = "dnsdiag" -version = "2.9.2" +version = "2.9.3" description = "DNS Measurement, Troubleshooting and Security Auditing Toolset (ping, traceroute)" readme = "README.md" requires-python = ">=3.10" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.9.2/tests/test_dnstraceroute_pytest.py new/dnsdiag-2.9.3/tests/test_dnstraceroute_pytest.py --- old/dnsdiag-2.9.2/tests/test_dnstraceroute_pytest.py 2026-01-13 11:12:08.000000000 +0100 +++ new/dnsdiag-2.9.3/tests/test_dnstraceroute_pytest.py 2026-02-03 18:18:21.000000000 +0100 @@ -170,6 +170,41 @@ assert "2001:4860:4860::8888" in result.output +class TestProtocols: + """Tests for different DNS protocols in traceroute mode""" + + @pytest.mark.parametrize("resolver_name,resolver_ip", [ + ('google', RESOLVERS_IPV4['google']), + ('cloudflare', RESOLVERS_IPV4['cloudflare']), + ]) + def test_tcp_traceroute(self, runner, resolver_name, resolver_ip): + """Test TCP traceroute (regression test for issue with EHOSTUNREACH)""" + result = runner.run(['-T', '-c', '3', '-s', resolver_ip, 'google.com']) + assert result.success, f"TCP traceroute failed: {result.error}" + assert "DNS:" in result.output + assert resolver_ip in result.output + assert "unexpected error" not in result.output.lower() + assert "[Errno 65]" not in result.output + + def test_quic_traceroute(self, runner): + """Test QUIC (DoQ) traceroute""" + result = runner.run(['-Q', '-c', '3', '-s', '94.140.14.14', 'wikimedia.org']) + assert result.success, f"QUIC traceroute failed: {result.error}" + assert "DNS:" in result.output + assert "94.140.14.14" in result.output + + @pytest.mark.parametrize("resolver_ip", [ + RESOLVERS_IPV4['google'], + RESOLVERS_IPV4['cloudflare'], + ]) + def test_http3_traceroute(self, runner, resolver_ip): + """Test HTTP/3 (DoH3) traceroute""" + result = runner.run(['-3', '-c', '3', '-s', resolver_ip, 'google.com']) + assert result.success, f"HTTP/3 traceroute failed: {result.error}" + assert "DNS:" in result.output + assert resolver_ip in result.output + + class TestCLIOptions: """Tests for various CLI options""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.9.2/tests/test_shared.py new/dnsdiag-2.9.3/tests/test_shared.py --- old/dnsdiag-2.9.2/tests/test_shared.py 2026-01-13 11:12:08.000000000 +0100 +++ new/dnsdiag-2.9.3/tests/test_shared.py 2026-02-03 18:18:21.000000000 +0100 @@ -5,7 +5,7 @@ """ import pytest -from dnsdiag.shared import valid_hostname +from dnsdiag.shared import valid_hostname, set_protocol_exclusive class TestHostnameValidation: @@ -159,5 +159,62 @@ assert valid_hostname('_test-123.example.com', allow_underscore=True) +class TestProtocolExclusive: + """Test protocol mutual exclusivity function""" + + def test_first_protocol_succeeds(self): + """First protocol option should succeed""" + proto, option = set_protocol_exclusive(1, "-T", None) + assert proto == 1 + assert option == "-T" + + def test_second_protocol_fails(self): + """Second protocol option should raise SystemExit""" + with pytest.raises(SystemExit): + set_protocol_exclusive(2, "-H", "-T") + + def test_long_option_names(self): + """Test with long option names""" + proto, option = set_protocol_exclusive(1, "--tcp", None) + assert proto == 1 + assert option == "--tcp" + + def test_error_shows_conflicting_options(self): + """Error message should show both conflicting options""" + with pytest.raises(SystemExit) as exc_info: + set_protocol_exclusive(2, "-H", "-T") + + # The die() function prints to stderr and exits, we can't capture + # the message directly, but we can verify it exits with code 1 + + def test_multiple_different_protocols(self): + """Test various protocol constant values""" + # Test with different protocol values + proto1, opt1 = set_protocol_exclusive(10, "-X", None) + assert proto1 == 10 + assert opt1 == "-X" + + # Second call should fail + with pytest.raises(SystemExit): + set_protocol_exclusive(20, "-Q", "-X") + + def test_same_protocol_twice_fails(self): + """Setting same protocol twice should fail""" + proto1, opt1 = set_protocol_exclusive(5, "-T", None) + assert proto1 == 5 + + # Even same protocol should fail if already set + with pytest.raises(SystemExit): + set_protocol_exclusive(5, "-T", "-T") + + def test_return_type(self): + """Test return type is tuple of int and str""" + result = set_protocol_exclusive(1, "-T", None) + assert isinstance(result, tuple) + assert len(result) == 2 + assert isinstance(result[0], int) + assert isinstance(result[1], str) + + if __name__ == '__main__': pytest.main([__file__, '-v'])
