<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p>Hi,</p>
<p>I think this could be a useful addition. The apidoc would need to
be clear about the differences from the existing literal parsing
method and any implications for ambiguity between octal and
decimal formats spelled out.</p>
<p>- Michael<br>
</p>
<div class="moz-cite-prefix">On 28/03/2024 19:09, Sergey Chernyshev
wrote:<br>
</div>
<blockquote type="cite" cite="mid:0078e435-2d23-4803-8828-fc5976544181@bell-sw.com">
<p>Hi Net Dev team, </p>
<p>I posted this earlier to core-libs-dev mailing list, which was
not a proper place to discuss the net issues. Thanks Alan
Bateman for directing me to the right place.<br>
</p>
<p>I would like to propose a PR to extend the InetAddress API in
JDK 23, namely to provide interface to constructing InetAddress
objects from literal addresses in POSIX/BSD form (please see the
discussion [1]), to the Apps that need to mimic the behavior of
POSIX network APIs (<code class="notranslate">inet_addr</code>)
used by standard network utilities such as netcat/curl/wget and
the majority of web browsers. At present time, there's no way to
construct <code class="notranslate">InetAddress</code> object
from such literal addresses because the new API <code class="notranslate">InetAddress.ofLiteral()</code> and <code class="notranslate">Inet4Address.ofLiteral()</code> will
consume an octal address and successfully parse it as decimal,
ignoring the octal prefix. Hence, the resulting object will
point to a different IP address than it is expected to point to.
There's also no direct way to create an InetAddress from a
literal address with hexadecimal segments, although this can be
the case in certain systems.<br>
</p>
<p dir="auto">Historically <code class="notranslate">InetAddress.getByName()/.getAllByName()</code>
were the only way to convert a literal address into an
InetAddress object. <code class="notranslate">getAllByName()</code>
API relies on POSIX <code class="notranslate">getaddrinfo</code>
/ <code class="notranslate">inet_addr</code> which parses IP
address segments with <code class="notranslate">strtoul</code>
(accepts octal and hexadecimal bases). The fallback to <code class="notranslate">getaddrinfo</code> is undesirable as it
may end up with network queries (blocking mode), if <code class="notranslate">inet_aton</code> rejects the input literal
address. The Java standard explicitly says that</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto">
<pre class="notranslate"><code class="notranslate">"If a literal IP address is supplied, only the validity of the address format is checked."
</code></pre>
<div class="zeroclipboard-container position-absolute right-0 top-0"> </div>
</div>
<p dir="auto">Aleksei Efimov contributed JDK-8272215 [2] that adds
new factory methods <code class="notranslate">.ofLiteral()</code>
to <code class="notranslate">InetAddress</code> classes.
Although the new API is not affected by the <code class="notranslate">getaddrinfo</code> fallback issue, it is
not sufficient for an app that wants to mimic the behavior of
BSD/POSIX network utlilities. In particular, Java apps that
involve parsing or interpreting the parameters of the standard
tools as well as their configuration / environment.<br>
</p>
It is suggested to add a new factory method such as <code class="notranslate">.ofPosixLiteral()</code> to <code class="notranslate">Inet4Address</code> class to fill this gap.
This won't introduce ambiguity into the API and won't break the
long standing behavior. As a new method, it will not affect Java
utilities such as HttpClient, nor the existing Java applications.
At the same time, the new method will help dealing with confusion
between BSD and Java standards.
<p dir="auto">The parsing algorithm was added as part of
JDK-8277608 [3]. It requires minor modification to produce 4
bytes output (now it doesn't produce any output). The algorithm
allows up to 4 segments splitted by dots (.), the leading
segment(s) must not exceed 255 if there are more than 1 segment,
the trailing segment must not exceed <font face="monospace">256ˆ(5
- numberOfSegments) - 1</font>. The algorithm rejects numbers
greater than 0xFF hex, 0377 octal, 255 decimal per octet. It is
different to <font face="monospace">.ofLiteral()</font> where
it is simply 255 per octet, regardless of leading 0s (the total
length must not exceed 15). In <font face="monospace">.ofPosixLiteral()</font>
there'd be no limit of the number of leading 0s, which is also
the case with <font face="monospace">inet_addr()</font>. The
corner case for both methods are numbers that are accepted in
both, but produce different outputs such as octal numbers
between 010 and 0255. 0256 and above are rejected by ofLiteral()
as well as all hexadecimal numbers. Zero prefixed decimal
numbers such as 0239 should be rejected by ofPosixLiteral().<br>
</p>
<p>There could be a slight <span class="HwtZe" lang="en"><span class="jCAhz ChMk0b"><span class="ryNqvb">discrepancy</span></span></span>
in terms of how different standard tools are working under
different OS. For example in MacOS wget & nc disregard octal
prefix (0) while allowing hexadecimal prefix (0x), at the same
time curl & ping process both prefixes. In Ubuntu Server
22.04 both prefixes are processed, but they are not allowed in
/etc/hosts file, while in MacOS it's legal to use 0x. Despite
the deviations in how and where the BSD standard is implemented,
there are two distinct approaches. I don't see why Java should't
provide two different indepentent APIs. It would give the future
apps flexibility to decide which standard to rely on, ability to
see the full picture.<br>
</p>
<p dir="auto">Please share your thoughts on whether such a change
might be desirable in JDK 23. Thank you for your help! </p>
<p dir="auto">Best regards<br>
Sergey Chernyshev</p>
[1] <span style=""><a class="moz-txt-link-freetext" href="https://bugs.openjdk.org/browse/JDK-8315767" moz-do-not-send="true">https://bugs.openjdk.org/browse/JDK-8315767</a></span><br>
[2] <span style=""><a class="moz-txt-link-freetext" href="https://bugs.openjdk.org/browse/JDK-8272215" moz-do-not-send="true">https://bugs.openjdk.org/browse/JDK-8272215</a><br>
</span>[3] <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jdk/commit/cdc1582" moz-do-not-send="true">https://github.com/openjdk/jdk/commit/cdc1582</a>
</blockquote>
</body>
</html>