-
Notifications
You must be signed in to change notification settings - Fork 7.7k
win-fix: correct hostname normalization condition for loopback addresses #43634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
||
// On Windows, reverse lookup for loopback may return the IP (e.g., 127.0.0.1) instead of 'localhost'. Normalize to 'localhost' for consistent domain checks. | ||
if (hostname.equals(address.getHostAddress()) && address.isLoopbackAddress()) { | ||
if (!hostname.equals(address.getHostAddress()) && address.isLoopbackAddress()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To match the existing comment and cover the case of resolving to an ip or non-localhost, you could use:
if (!hostname.equals(address.getHostAddress()) && address.isLoopbackAddress()) { | |
if (NetworkUtils.checkForWindows() && address.isLoopbackAddress()) { |
Alternatively if the hostname cannot return the ip, then the comment needs changed.
Or if we are documenting in some way that localhost is always the cannonical hostname for loopback, then we can also just unconditionally do:
if (address.isLoopbackAddress()) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, Steve!
I mentioned the removal of the first condition during the meeting as the second option. @vmuzikar any preference here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for just keeping the second condition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks guys. Given that we removed the first condition, I rearranged the code a bit and added a note to the Client Registration guide as Steve suggested. Is that ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unreported flaky test detected, please review
Unreported flaky test detectedIf the flaky tests below are affected by the changes, please review and update the changes accordingly. Otherwise, a maintainer should report the flaky tests prior to merging the PR. org.keycloak.testsuite.account.AccountRestServiceTest#listApplicationsWithoutPermissionKeycloak CI - Java Distribution IT (windows-latest - temurin - 25)
|
532efd4
to
3b83ef4
Compare
hostname = "localhost"; | ||
} | ||
|
||
if (hostname.equals(address.getHostAddress())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To double-check - this is ok, if the original comment was wrong. That is windows won't resolve 127.0.0.1 to 127.0.0.1, it will always be to a hostname, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, as I mentioned previously during our discussions, I am hesitant to say that it is a general rule that I am 100% certain about.
Having said that, I can confirm that's the case in our CI and on my W11 machine - 127.0.0.1 resolves to a hostname on Windows, thus this PR helped to stabilize the failing test. So when it comes to IPv4 environments I would be pretty much certain.
I know that your question was specifically regarding the IPv4, but when it comes to IPv6, that's where I am less certain.
Because, at least during my tries to mimic IPv6 scenario, ::1
could be resolved to 0:0:0:0:0:0:0:1
. On the OS level/.NET stack it wasn't so obvious - it returned machine's hostname. But in terms of Java/JVM I noticed that hostname = "0:0:0:0:0:0:0:1"
and address.getHostAddress() = "0:0:0:0:0:0:0:1"
- both return literal strings that are equal, which means a null would be returned, even though it’s a legitimate loopback. So there seems to be an inconsistency between OS and JVM.
I am not sure if our goal is to tackle it in this PR, but do you think that a simple reorder would be enough to completely cover it? Something like:
if (address.isLoopbackAddress()) {
hostname = "localhost";
} else if (hostname.equals(address.getHostAddress())) {
logger.debugf("The hostAddress '%s' was not resolved to a hostname", hostAddress);
return null;
}
Or do we keep going in circles with this?
Thanks for your time!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here are some logs I gathered during testing:
PS C:\Users\pepo4> @('127.0.0.1','::1','203.0.113.1') | ForEach-Object {
$ip = $_
try {
$entry = [System.Net.Dns]::GetHostEntry([System.Net.IPAddress]::Parse($ip))
[PSCustomObject]@{
Query = $ip
HostName = $entry.HostName
}
} catch {
[PSCustomObject]@{
Query = $ip
HostName = "(error: $($_.Exception.Message))"
AddressList = ''
}
}
} | Format-Table -AutoSize
Query HostName
----- --------
127.0.0.1 kubernetes.docker.internal
::1 Lenovo15ARH7
203.0.113.1 (error: Exception calling "GetHostEntry" with "1" argument(s): "No such host is known")
PS C:\Users\pepo4> @'
import java.net.*;
String[] ips = { "127.0.0.1", "::1", "203.0.113.1" };
for (String ip : ips) {
try {
InetAddress address = InetAddress.getByName(ip);
System.out.println("Query: " + ip
+ " HostName: " + address.getHostName()
+ " HostAddress: " + address.getHostAddress()
+ " isLoopbackAddress(): " + address.isLoopbackAddress());
} catch (Exception e) {
System.out.println("Query: " + ip + " Error: " + e.getMessage());
}
}
/exit
'@ | jshell
| Welcome to JShell -- Version 21.0.6
| For an introduction type: /help intro
jshell :
At line:18 char:6
+ '@ | jshell
+ ~~~~~~
+ CategoryInfo : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
jshell>
jshell>
ips ==> String[3] { "127.0.0.1", "::1", "203.0.113.1" }
jshell> String[] ips = { "127.0.0.1", "::1", "203.0.113.1" }
jshell>
jshell> for (String ip : ips) {
...> try {
...> InetAddress address = InetAddress.getByName(ip);
...> System.out.println("Query: " + ip
...> + " HostName: " + address.getHostName()
...> + " HostAddress: " + address.getHostAddress()
...> + " isLoopbackAddress(): " + address.isLoopbackAddress());
...> }} catch (Exception e) {
...> System.out.println("Query: " + ip + " Error: " + e.getMessage());
...> }}
Query: 127.0.0.1 HostName: kubernetes.docker.internal HostAddress: 127.0.0.1 isLoopbackAddress(): true
Query: ::1 HostName: 0:0:0:0:0:0:0:1 HostAddress: 0:0:0:0:0:0:0:1 isLoopbackAddress(): true
Query: 203.0.113.1 HostName: 203.0.113.1 HostAddress: 203.0.113.1 isLoopbackAddress(): false
...> }
| Goodbye
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if our goal is to tackle it in this PR, but do you think that a simple reorder would be enough to completely cover it? Something like:
Yes, that is exactly what I would expect and it matches the new doc note.
Closes: keycloak#42794 Co-authored-by: Steven Hawkins <[email protected]> Signed-off-by: Peter Zaoral <[email protected]>
3b83ef4
to
ce93bf4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you @Pepo48
Closes: #42794