Skip to content

Add confirmed family members and reverse DNS details to relay dialog#465

Merged
JuliusHenke merged 12 commits intomasterfrom
issue-26-relay-details
May 1, 2026
Merged

Add confirmed family members and reverse DNS details to relay dialog#465
JuliusHenke merged 12 commits intomasterfrom
issue-26-relay-details

Conversation

@JuliusHenke
Copy link
Copy Markdown
Member

@JuliusHenke JuliusHenke commented May 1, 2026

Closes #451 with minor refactoring. @center2055 thanks a lot for your nice PR. Fixes #26.

Co-authored-by: @center2055

Your Name and others added 6 commits March 18, 2026 08:47
Copilot AI review requested due to automatic review settings May 1, 2026 13:05
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

Visit the preview URL for this PR (updated for commit fd74b50):

https://tormap-36f44--pr465-issue-26-relay-detai-lnjmdny2.web.app

(expires Sun, 31 May 2026 13:46:03 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: 0c1f71965de18e60b0e686b0d0356977fec090dc

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds enriched relay details (confirmed family members + reverse DNS hostnames) to the relay details dialog, including backend lookup/caching and UI actions to display/select the confirmed family on the map.

Changes:

  • Backend: introduce reverse-DNS lookup service with caching and a query service that enriches relay details responses.
  • Backend API: switch relay details endpoint to return a dedicated DTO including confirmed family members + verified/unverified hostnames.
  • Frontend: extend DTO/types and render new relay dialog sections, including a “show confirmed family” action.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
frontend/src/dto/relay.ts Extends relay details DTO with familyId + reverse DNS + confirmed family members; adjusts AS number typing.
frontend/src/components/dialogs/relay/RelayDetailsTable.tsx Renders confirmed family members + reverse DNS sections and adds “show family on map” action.
frontend/src/components/dialogs/relay/RelayDetailsDialogSmall.tsx Passes closeDialog into details table for post-action behavior.
frontend/src/components/dialogs/relay/RelayDetailsDialogLarge.tsx Passes closeDialog into details table for post-action behavior.
frontend/src/components/buttons/SelectFamilyButton.tsx Adds optional labeled (non-icon) button variant and reuses selection handler.
backend/src/test/kotlin/org/tormap/service/ReverseDnsLookupServiceTest.kt Unit tests for verified vs unverified hostname separation and empty-result behavior.
backend/src/test/kotlin/org/tormap/service/RelayDetailsQueryServiceTest.kt Unit tests for relay enrichment (family members + reverse DNS) and not-found behavior.
backend/src/test/kotlin/org/tormap/config/CacheConfigTest.kt Ensures the new reverse DNS cache is created and cleared in tests.
backend/src/main/kotlin/org/tormap/service/ReverseDnsLookupService.kt Implements reverse DNS lookup + forward-confirmation and caches results.
backend/src/main/kotlin/org/tormap/service/RelayDetailsQueryService.kt Adds query service to assemble enriched relay details DTO from DB + reverse DNS.
backend/src/main/kotlin/org/tormap/config/CacheConfig.kt Adds Ehcache config for reverse DNS lookup results with 6h TTL.
backend/src/main/kotlin/org/tormap/adapter/dto/RelayDetailsDto.kt New DTO that exposes confirmed family members and reverse DNS hostnames.
backend/src/main/kotlin/org/tormap/adapter/controller/RelayDetailsController.kt Switches relay details endpoint to return enriched DTO via query service.
backend/build.gradle.kts Adds dnsjava dependency for reverse DNS lookups.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

InetAddress.getAllByName(hostName)
.filterNot { it.isPubliclyRoutable() }
.map { it.hostAddress }
} catch (_: UnknownHostException) {
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lookupAddresses only catches UnknownHostException, but InetAddress.getAllByName (or the subsequent address processing) can still throw runtime exceptions (e.g., SecurityException, unexpected parsing issues). Since lookupHostNames doesn’t catch these, a single bad PTR hostname could cause a 500 for the relay-details endpoint. Consider catching a broader Exception here (as done in lookupPtrRecords) and returning emptyList() (optionally with a log at debug/warn level).

Suggested change
} catch (_: UnknownHostException) {
} catch (_: Exception) {

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Implement this with a debug logger for exceptions on this and other parts of the service

Comment on lines +47 to +62
private fun InetAddress.isULA(): Boolean =
this is Inet6Address &&
(address[0].toInt() and 0xFE) == 0xFC // fc00::/7

private fun InetAddress.isPubliclyRoutable(): Boolean =
isLoopbackAddress ||
isLinkLocalAddress ||
isSiteLocalAddress || // reliable for IPv4
isULA() || // fills the IPv6 gap isSiteLocalAddress misses
isMulticastAddress ||
isAnyLocalAddress ||
address.first() == 0.toByte() ||
(address.size == 4 &&
address[0] == 100.toByte() &&
(address[1].toInt() and 0xFF) in 64..127)
}
Copy link

Copilot AI May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The helper isPubliclyRoutable() currently returns true for addresses that are not publicly routable (loopback/link-local/site-local/ULA/multicast/CGNAT, etc.), and callers rely on this inversion via filterNot { it.isPubliclyRoutable() }. Renaming it to something like isNotPubliclyRoutable (or inverting the predicate and adjusting the filter) would make the intent clearer and reduce the risk of future misuse.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 646982c. Inverted the isPubliclyRoutable() predicate so it now correctly returns true for publicly routable addresses (negating all the non-routable conditions), and changed the call site from filterNot to filter to match.

Copy link
Copy Markdown
Contributor

Copilot AI commented May 1, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • collector.torproject.org
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java -Dorg.gradle.internal.worker.tmpdir=/home/REDACTED/work/tormap/tormap/backend/build/tmp/test/work @/home/REDACTED/.gradle/.tmp/gradle-worker-classpath3845826778364404920txt -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -ea worker.org.gradle.process.internal.worker.GradleWorkerMain 'Gradle Test Executor 1' (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI and others added 2 commits May 1, 2026 13:22
Copy link
Copy Markdown
Contributor

Copilot AI commented May 1, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • collector.torproject.org
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java -Dorg.gradle.internal.worker.tmpdir=/home/REDACTED/work/tormap/tormap/backend/build/tmp/test/work @/home/REDACTED/.gradle/.tmp/gradle-worker-classpath6996109766756294891txt -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -ea worker.org.gradle.process.internal.worker.GradleWorkerMain 'Gradle Test Executor 1' (dns block)
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java -Dorg.gradle.internal.worker.tmpdir=/home/REDACTED/work/tormap/tormap/backend/build/tmp/test/work @/home/REDACTED/.gradle/.tmp/gradle-worker-classpath14725746462298803059txt -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -ea worker.org.gradle.process.internal.worker.GradleWorkerMain 'Gradle Test Executor 2' (dns block)
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java -Dorg.gradle.internal.worker.tmpdir=/home/REDACTED/work/tormap/tormap/backend/build/tmp/test/work @/home/REDACTED/.gradle/.tmp/gradle-worker-classpath2975394841889527095txt -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -ea worker.org.gradle.process.internal.worker.GradleWorkerMain 'Gradle Test Executor 3' (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@JuliusHenke JuliusHenke merged commit 1632225 into master May 1, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add more relay details to dialog

3 participants