< prev index next >

test/jdk/com/sun/jndi/dns/lib/DNSServer.java

Print this page

        

*** 24,33 **** --- 24,35 ---- import sun.security.util.HexDumpEncoder; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; + import java.net.InetAddress; + import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List;
*** 47,57 **** * xxxx: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff ................ * * Typically, DNS protocol exchange is generated by DNSTracer who captures * communication messages between DNS application program and real DNS server */ ! public class DNSServer implements Runnable { public class Pair<F, S> { private F first; private S second; --- 49,59 ---- * xxxx: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff ................ * * Typically, DNS protocol exchange is generated by DNSTracer who captures * communication messages between DNS application program and real DNS server */ ! public class DNSServer extends Thread implements Server { public class Pair<F, S> { private F first; private S second;
*** 85,107 **** private DatagramSocket socket; private String filename; private boolean loop; private final List<Pair<byte[], byte[]>> cache = new ArrayList<>(); private ByteBuffer reqBuffer = ByteBuffer.allocate(DNS_PACKET_SIZE); ! public DNSServer(DatagramSocket socket, String filename) { ! this(socket, filename, false); } ! public DNSServer(DatagramSocket socket, String filename, boolean loop) { ! this.socket = socket; this.filename = filename; this.loop = loop; } public void run() { try { System.out.println( "DNSServer: Loading DNS cache data from : " + filename); loadCaptureFile(filename); System.out.println( --- 87,111 ---- private DatagramSocket socket; private String filename; private boolean loop; private final List<Pair<byte[], byte[]>> cache = new ArrayList<>(); private ByteBuffer reqBuffer = ByteBuffer.allocate(DNS_PACKET_SIZE); + private volatile boolean isRunning; ! public DNSServer(String filename) throws SocketException { ! this(filename, false); } ! public DNSServer(String filename, boolean loop) throws SocketException { ! this.socket = new DatagramSocket(0, InetAddress.getLoopbackAddress()); this.filename = filename; this.loop = loop; } public void run() { try { + isRunning = true; System.out.println( "DNSServer: Loading DNS cache data from : " + filename); loadCaptureFile(filename); System.out.println(
*** 110,156 **** System.out.println("DNSServer: loop playback: " + loop); int playbackIndex = 0; while (playbackIndex < cache.size()) { ! DatagramPacket reqPacket = new DatagramPacket(reqBuffer.array(), ! reqBuffer.array().length); ! socket.receive(reqPacket); ! ! System.out.println( ! "DNSServer: received query message from " + reqPacket ! .getSocketAddress()); if (!verifyRequestMsg(reqPacket, playbackIndex)) { throw new RuntimeException( "DNSServer: Error: Failed to verify DNS request. " + "Not identical request message : \n" + encoder.encodeBuffer( Arrays.copyOf(reqPacket.getData(), reqPacket.getLength()))); } ! byte[] payload = generateResponsePayload(reqPacket, ! playbackIndex); ! socket.send(new DatagramPacket(payload, payload.length, ! reqPacket.getSocketAddress())); ! System.out.println( ! "DNSServer: send response message to " + reqPacket ! .getSocketAddress()); playbackIndex++; if (loop && playbackIndex >= cache.size()) { playbackIndex = 0; } } System.out.println( "DNSServer: Done for all cached messages playback"); } catch (Exception e) { System.err.println("DNSServer: Error: " + e); } } /* * Load a capture file containing an DNS protocol exchange in the * hexadecimal dump format emitted by sun.misc.HexDumpEncoder: * --- 114,198 ---- System.out.println("DNSServer: loop playback: " + loop); int playbackIndex = 0; while (playbackIndex < cache.size()) { ! DatagramPacket reqPacket = receiveQuery(); if (!verifyRequestMsg(reqPacket, playbackIndex)) { + if (playbackIndex > 0 && verifyRequestMsg(reqPacket, + playbackIndex - 1)) { + System.out.println( + "DNSServer: received retry query, resend"); + playbackIndex--; + } else { throw new RuntimeException( "DNSServer: Error: Failed to verify DNS request. " + "Not identical request message : \n" + encoder.encodeBuffer( Arrays.copyOf(reqPacket.getData(), reqPacket.getLength()))); } + } ! sendResponse(reqPacket, playbackIndex); playbackIndex++; if (loop && playbackIndex >= cache.size()) { playbackIndex = 0; } } System.out.println( "DNSServer: Done for all cached messages playback"); + + System.out.println( + "DNSServer: Still listening for possible retry query"); + while (true) { + DatagramPacket reqPacket = receiveQuery(); + + // here we only handle the retry query for last one + if (!verifyRequestMsg(reqPacket, playbackIndex - 1)) { + throw new RuntimeException( + "DNSServer: Error: Failed to verify DNS request. " + + "Not identical request message : \n" + + encoder.encodeBuffer( + Arrays.copyOf(reqPacket.getData(), + reqPacket.getLength()))); + } + + sendResponse(reqPacket, playbackIndex - 1); + } } catch (Exception e) { + if (isRunning) { System.err.println("DNSServer: Error: " + e); + e.printStackTrace(); + } else { + System.out.println("DNSServer: Exit"); } } + } + + private DatagramPacket receiveQuery() throws IOException { + DatagramPacket reqPacket = new DatagramPacket(reqBuffer.array(), + reqBuffer.array().length); + socket.receive(reqPacket); + + System.out.println("DNSServer: received query message from " + reqPacket + .getSocketAddress()); + + return reqPacket; + } + + private void sendResponse(DatagramPacket reqPacket, int playbackIndex) + throws IOException { + byte[] payload = generateResponsePayload(reqPacket, playbackIndex); + socket.send(new DatagramPacket(payload, payload.length, + reqPacket.getSocketAddress())); + System.out.println("DNSServer: send response message to " + reqPacket + .getSocketAddress()); + } /* * Load a capture file containing an DNS protocol exchange in the * hexadecimal dump format emitted by sun.misc.HexDumpEncoder: *
*** 297,302 **** --- 339,363 ---- if ('a' <= ch && ch <= 'f') { return ch - 'a' + 10; } return -1; } + + @Override public void stopServer() { + isRunning = false; + if (socket != null) { + try { + socket.close(); + } catch (Exception e) { + // ignore + } + } + } + + @Override public int getPort() { + if (socket != null) { + return socket.getLocalPort(); + } else { + return -1; + } + } }
< prev index next >