Path: blob/master/test/jdk/com/sun/jndi/dns/ConfigTests/TcpTimeout.java
41155 views
/*1* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import jtreg.SkippedException;2425import javax.naming.directory.InitialDirContext;26import java.io.IOException;27import java.net.BindException;28import java.net.InetAddress;29import java.net.ServerSocket;3031import static java.util.concurrent.TimeUnit.NANOSECONDS;32import static jdk.test.lib.Utils.adjustTimeout;3334/*35* @test36* @bug 822858037* @summary Tests that we get a DNS response when the UDP DNS server returns a38* truncated response and the TCP DNS server does not respond at all39* after connect.40* @library ../lib/41* @library /test/lib42* @modules java.base/sun.security.util43* @run main TcpTimeout44* @run main TcpTimeout -Dcom.sun.jndi.dns.timeout.initial=500045*/4647public class TcpTimeout extends DNSTestBase {48private TcpDnsServer tcpDnsServer;4950/* The acceptable variation in timeout measurement. */51private static final long TOLERANCE = adjustTimeout(5_000);5253/* The acceptable variation of early returns from timed socket operations. */54private static final long PREMATURE_RETURN = adjustTimeout(100);5556public static void main(String[] args) throws Exception {57new TcpTimeout().run(args);58}5960@Override61public void runTest() throws Exception {62/* The default timeout value is 1 second, as stated in the63jdk.naming.dns module docs. */64long timeout = 1_000;65var envTimeout = env().get("com.sun.jndi.dns.timeout.initial");66if (envTimeout != null)67timeout = Long.parseLong(String.valueOf(envTimeout));6869setContext(new InitialDirContext(env()));7071long startNanos = System.nanoTime();7273/* perform query */74var attrs = context().getAttributes("host1");7576long elapsed = NANOSECONDS.toMillis(System.nanoTime() - startNanos);77if (elapsed < timeout - PREMATURE_RETURN || elapsed > timeout + TOLERANCE) {78throw new RuntimeException(String.format(79"elapsed=%s, timeout=%s, TOLERANCE=%s, PREMATURE_RETURN=%s",80elapsed, timeout, TOLERANCE, PREMATURE_RETURN));81}8283DNSTestUtils.debug(attrs);8485/* Note that the returned attributes are truncated and the response86is not valid. */87var txtAttr = attrs.get("TXT");88if (txtAttr == null)89throw new RuntimeException("TXT attribute missing.");90}9192@Override93public void initTest(String[] args) {94/* We need to bind the TCP server on the same port the UDP server is95listening to. This may not be possible if that port is in use. Retry96MAX_RETRIES times relying on UDP port randomness. */97final int MAX_RETRIES = 5;98for (int i = 0; i < MAX_RETRIES; i++) {99super.initTest(args);100var udpServer = (Server) env().get(DNSTestUtils.TEST_DNS_SERVER_THREAD);101int port = udpServer.getPort();102try {103tcpDnsServer = new TcpDnsServer(port);104break; // success105} catch (BindException be) {106DNSTestUtils.debug("Failed to bind server socket on port " + port107+ ", retry no. " + (i + 1) + ", " + be.getMessage());108} catch (Exception ex) {109throw new RuntimeException("Unexpected exception during initTest", ex);110} finally {111if (tcpDnsServer == null) { // cleanup behind exceptions112super.cleanupTest();113}114}115}116117if (tcpDnsServer == null) {118throw new SkippedException("Cannot start TCP server after "119+ MAX_RETRIES120+ " tries, skip the test");121}122}123124@Override125public void cleanupTest() {126super.cleanupTest();127if (tcpDnsServer != null)128tcpDnsServer.stopServer();129}130131/**132* A TCP server that accepts a connection and does nothing else: causes read133* timeout on client side.134*/135private static class TcpDnsServer {136final ServerSocket serverSocket;137138TcpDnsServer(int port) throws IOException {139serverSocket = new ServerSocket(port, 0, InetAddress.getLoopbackAddress());140System.out.println("TcpDnsServer: listening on port " + port);141}142143void stopServer() {144try {145if (serverSocket != null)146serverSocket.close();147} catch (Exception ignored) { }148}149}150}151152153