Skip to content

Privacy do not check reachability#1047

Merged
ArneBab merged 6 commits into
hyphanet:nextfrom
ArneBab:privacy--do-not-check-reachability
Jun 28, 2025
Merged

Privacy do not check reachability#1047
ArneBab merged 6 commits into
hyphanet:nextfrom
ArneBab:privacy--do-not-check-reachability

Conversation

@ArneBab

@ArneBab ArneBab commented Apr 5, 2025

Copy link
Copy Markdown
Contributor

No description provided.

With IPv6 the standard check of Javva can send tcp/7 requests instead
of standard PINGs, so this reachability check makes nodes too visible
from the network level.
@ArneBab ArneBab force-pushed the privacy--do-not-check-reachability branch from ea10cf5 to f530e11 Compare April 5, 2025 07:55
@bertm

bertm commented May 10, 2025

Copy link
Copy Markdown
Contributor

This class has become a bit of a mess of tangled conditions, and through all the negations, ones and minus-ones it's somewhat difficult to review whether the logic here is sound.

If we define a clever helper method prefer that takes a Predicate<InetAddress> and returns a Comparator<InetAddress> and extract the cached isReachable check to a separate method, we could reduce this to the more descriptive below definition using Comparator's thenComparing chaining operations (assuming I reverse engineered this correctly 😃):

private final Comparator<InetAddress> innerComparator = prefer(Objects::nonNull)
		.thenComparing(prefer(not(InetAddress::isAnyLocalAddress)))
		.thenComparing(prefer(not(InetAddress::isLoopbackAddress)))
		.thenComparing(prefer(not(InetAddress::isLinkLocalAddress)))
		.thenComparing(prefer(is(InetAddress::isSiteLocalAddress).and(this::isReachable)))
		// NOTE: the last 3 lines below can also be replaced by simply 
		//   .thenComparing(InetAddressComparator.COMPARATOR);
		.thenComparing(prefer(is(Inet6Address.class::isInstance)))
		.thenComparingInt(Object::hashCode)
		.thenComparing(InetAddress::getAddress, Fields::compareBytes);

With the above defined, the actual compare implementation can be simplified to just a few lines:

@Override
public int compare(InetAddress arg0, InetAddress arg1) {
	if (Objects.equals(arg0, arg1)) {
		return 0;
	}
	return innerComparator.compare(arg0, arg1);
}

Comment thread src/freenet/support/io/InetAddressIpv6FirstComparator.java Outdated
@ArneBab

ArneBab commented May 11, 2025

Copy link
Copy Markdown
Contributor Author

This class has become a bit of a mess of tangled conditions, and through all the negations, ones and minus-ones it's somewhat difficult to review whether the logic here is sound.

private final Comparator<InetAddress> innerComparator = prefer(Objects::nonNull)
...

That looks much nicer, yes. I’ll try to get there. Thank you!

@ArneBab

ArneBab commented Jun 22, 2025

Copy link
Copy Markdown
Contributor Author

We only have not since Java 11, so I implemented both prefer and preferNot.

@ArneBab

ArneBab commented Jun 27, 2025

Copy link
Copy Markdown
Contributor Author

@bertm could you have another look whether this is OK to be merged?

@Bombe

Bombe commented Jun 27, 2025

Copy link
Copy Markdown
Contributor

Oh, snap, here’s a PR where I haven’t complained about missing tests yet! 🤣

@bertm bertm left a comment

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.

This looks way more comprehensible already. Here's a few additional but minor remarks.


// inverted prefer, because not(...) is only documented since Java 11
private Comparator<InetAddress> preferNot(Predicate<InetAddress> pred) {
return (arg0, arg1) -> -1 * predicateToCompare(pred, arg0, arg1);

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.

This can be simplified to return prefer(pred).reversed();.

return Fields.compareBytes(bytes0, bytes1);
// Hostnames in InetAddress are merely cached, equals() only operates on the byte[].
private Comparator<InetAddress> prefer(Predicate<InetAddress> pred) {
return (arg0, arg1) -> predicateToCompare(pred, arg0, arg1);

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.

This can be simplified to return (arg0, arg1) -> Boolean.compare(!pred.test(arg0), !pred.test(arg1));

Also avoids having to test the predicates twice.

Comment on lines +71 to +73
if (pred.test(arg0) && pred.test(arg1)) {
return 0;
}

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.

The indentation is off, but this code can probably be removed as per the other comments.

@ArneBab ArneBab force-pushed the privacy--do-not-check-reachability branch from 5ba4224 to e22696c Compare June 28, 2025 18:17
@ArneBab ArneBab force-pushed the privacy--do-not-check-reachability branch from e22696c to ef74bc0 Compare June 28, 2025 18:18
@ArneBab ArneBab merged commit 0aba0d0 into hyphanet:next Jun 28, 2025
1 check passed
@ArneBab

ArneBab commented Jun 28, 2025

Copy link
Copy Markdown
Contributor Author

Merged - thank you! @Bombe @bertm

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.

3 participants