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