<!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>