< prev index next >

src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsClient.java

Print this page

        

*** 28,37 **** --- 28,38 ---- import java.io.IOException; import java.net.DatagramSocket; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.Socket; + import java.net.SocketTimeoutException; import java.security.SecureRandom; import javax.naming.*; import java.util.Collections; import java.util.Map;
*** 80,90 **** private static final int DEFAULT_PORT = 53; private static final int TRANSACTION_ID_BOUND = 0x10000; private static final SecureRandom random = JCAUtil.getSecureRandom(); private InetAddress[] servers; private int[] serverPorts; ! private int timeout; // initial timeout on UDP queries in ms private int retries; // number of UDP retries private final Object udpSocketLock = new Object(); private static final DNSDatagramSocketFactory factory = new DNSDatagramSocketFactory(random); --- 81,91 ---- private static final int DEFAULT_PORT = 53; private static final int TRANSACTION_ID_BOUND = 0x10000; private static final SecureRandom random = JCAUtil.getSecureRandom(); private InetAddress[] servers; private int[] serverPorts; ! private int timeout; // initial timeout on UDP and TCP queries in ms private int retries; // number of UDP retries private final Object udpSocketLock = new Object(); private static final DNSDatagramSocketFactory factory = new DNSDatagramSocketFactory(random);
*** 98,108 **** //------------------------------------------------------------------------- /* * Each server is of the form "server[:port]". IPv6 literal host names * include delimiting brackets. ! * "timeout" is the initial timeout interval (in ms) for UDP queries, * and "retries" gives the number of retries per server. */ public DnsClient(String[] servers, int timeout, int retries) throws NamingException { this.timeout = timeout; --- 99,109 ---- //------------------------------------------------------------------------- /* * Each server is of the form "server[:port]". IPv6 literal host names * include delimiting brackets. ! * "timeout" is the initial timeout interval (in ms) for queries, * and "retries" gives the number of retries per server. */ public DnsClient(String[] servers, int timeout, int retries) throws NamingException { this.timeout = timeout;
*** 235,252 **** } if (hdr.truncated) { // message is truncated -- try TCP // Try each server, starting with the one that just // provided the truncated message. for (int j = 0; j < servers.length; j++) { int ij = (i + j) % servers.length; if (doNotRetry[ij]) { continue; } try { Tcp tcp = ! new Tcp(servers[ij], serverPorts[ij]); byte[] msg2; try { msg2 = doTcpQuery(tcp, pkt); } finally { tcp.close(); --- 236,254 ---- } if (hdr.truncated) { // message is truncated -- try TCP // Try each server, starting with the one that just // provided the truncated message. + int retryTimeout = (timeout * (1 << retry)); for (int j = 0; j < servers.length; j++) { int ij = (i + j) % servers.length; if (doNotRetry[ij]) { continue; } try { Tcp tcp = ! new Tcp(servers[ij], serverPorts[ij], retryTimeout); byte[] msg2; try { msg2 = doTcpQuery(tcp, pkt); } finally { tcp.close();
*** 325,335 **** Exception caughtException = null; // Try each name server. for (int i = 0; i < servers.length; i++) { try { ! Tcp tcp = new Tcp(servers[i], serverPorts[i]); byte[] msg; try { msg = doTcpQuery(tcp, pkt); Header hdr = new Header(msg, msg.length); // Check only rcode as per --- 327,337 ---- Exception caughtException = null; // Try each name server. for (int i = 0; i < servers.length; i++) { try { ! Tcp tcp = new Tcp(servers[i], serverPorts[i], timeout); byte[] msg; try { msg = doTcpQuery(tcp, pkt); Header hdr = new Header(msg, msg.length); // Check only rcode as per
*** 460,482 **** /* * Returns the next DNS message from the TCP socket, or null on EOF. */ private byte[] continueTcpQuery(Tcp tcp) throws IOException { ! int lenHi = tcp.in.read(); // high-order byte of response length if (lenHi == -1) { return null; // EOF } ! int lenLo = tcp.in.read(); // low-order byte of response length if (lenLo == -1) { throw new IOException("Corrupted DNS response: bad length"); } int len = (lenHi << 8) | lenLo; byte[] msg = new byte[len]; int pos = 0; // next unfilled position in msg while (len > 0) { ! int n = tcp.in.read(msg, pos, len); if (n == -1) { throw new IOException( "Corrupted DNS response: too little data"); } len -= n; --- 462,484 ---- /* * Returns the next DNS message from the TCP socket, or null on EOF. */ private byte[] continueTcpQuery(Tcp tcp) throws IOException { ! int lenHi = tcp.read(); // high-order byte of response length if (lenHi == -1) { return null; // EOF } ! int lenLo = tcp.read(); // low-order byte of response length if (lenLo == -1) { throw new IOException("Corrupted DNS response: bad length"); } int len = (lenHi << 8) | lenLo; byte[] msg = new byte[len]; int pos = 0; // next unfilled position in msg while (len > 0) { ! int n = tcp.read(msg, pos, len); if (n == -1) { throw new IOException( "Corrupted DNS response: too little data"); } len -= n;
*** 681,703 **** } class Tcp { private Socket sock; ! java.io.InputStream in; java.io.OutputStream out; ! Tcp(InetAddress server, int port) throws IOException { sock = new Socket(server, port); sock.setTcpNoDelay(true); out = new java.io.BufferedOutputStream(sock.getOutputStream()); in = new java.io.BufferedInputStream(sock.getInputStream()); } void close() throws IOException { sock.close(); } } /* * javaos emulation -cj */ --- 683,733 ---- } class Tcp { private Socket sock; ! private java.io.InputStream in; java.io.OutputStream out; + private int timeoutLeft; ! Tcp(InetAddress server, int port, int timeout) throws IOException { sock = new Socket(server, port); sock.setTcpNoDelay(true); out = new java.io.BufferedOutputStream(sock.getOutputStream()); in = new java.io.BufferedInputStream(sock.getInputStream()); + timeoutLeft = timeout; } void close() throws IOException { sock.close(); } + + private interface SockerReadOp { + int read() throws IOException; + } + + private int readWithTimeout(SockerReadOp reader) throws IOException { + if (timeoutLeft <= 0) + throw new SocketTimeoutException(); + + sock.setSoTimeout(timeoutLeft); + long start = System.currentTimeMillis(); + try { + return reader.read(); + } + finally { + timeoutLeft -= System.currentTimeMillis() - start; + } + } + + int read() throws IOException { + return readWithTimeout(() -> in.read()); + } + + int read(byte b[], int off, int len) throws IOException { + return readWithTimeout(() -> in.read(b, off, len)); + } } /* * javaos emulation -cj */
< prev index next >