jDnsProxy/src/main/java/com/moparisthebest/dns/Util.java

272 lines
10 KiB
Java

package com.moparisthebest.dns;
import com.moparisthebest.dns.dto.Packet;
import java.io.*;
import java.nio.ByteBuffer;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
public class Util {
private Util() throws Exception {
throw new Exception("no instance for you");
}
public static Packet readTcpPacket(final DataInputStream dis) throws IOException {
final int length = dis.readUnsignedShort();
return readPacket(length, dis);
}
public static Packet readPacket(final int length, final DataInputStream dis) throws IOException {
//System.out.println("length: " + length);
final ByteBuffer bb = ByteBuffer.allocate(length);
final byte[] request = bb.array();
dis.readFully(request);
//System.out.println("request:");
//debugPacket(request);
return new Packet(bb);
}
public static void writeTcpPacket(final Packet p, final DataOutputStream dos) throws IOException {
dos.writeShort(p.getBuf().capacity());
dos.write(p.getBuf().array());
}
public static void tryClose(final AutoCloseable closeable) {
try {
closeable.close();
} catch (Throwable e) {
// ignore
}
}
public static <U> CompletableFuture<U> supplyAsyncOnTimeOut(final ScheduledExecutorService e, final long timeout, final TimeUnit unit, final Supplier<U> f) {
if (e == null || f == null) throw new NullPointerException();
final CompletableFuture<U> d = new CompletableFuture<>();
e.schedule(() -> {
if (!d.isDone()) {
try {
d.complete(f.get());
} catch (Throwable ex) {
d.completeExceptionally(ex);
}
}
}, timeout, unit);
return d;
}
/*
// temp debug code
public static void debugPacket(final byte[] packet) {
System.out.println(Base64.getUrlEncoder().encodeToString(packet));
//System.out.println(new Packet(ByteBuffer.wrap(packet, 2, packet.length - 2).slice()));
System.out.println(new Packet(ByteBuffer.wrap(packet).slice()));
printPrettyHexBytes(ByteBuffer.wrap(packet));
printPrettyChars(packet);
printPrettyDecimalUnsignedBytes(ByteBuffer.wrap(packet));
}
public static void printPrettyHexBytes(ByteBuffer bytes) {
bytes = bytes.slice();
System.out.println("-----------------------------");
int count = 0;
for (int x = 0; x < bytes.limit(); ++x) {
System.out.printf("%02X ", bytes.get(x));
if (++count == 8) {
System.out.println();
count = 0;
} else if (count % 2 == 0) {
System.out.print("| ");
}
}
System.out.println();
System.out.println("+++++++++++++++++++++++++++++");
}
public static void printPrettyChars(final byte[] bytes) {
System.out.println("-----------------------------");
int count = 0;
for (final byte b : bytes) {
System.out.printf("%02X(%c) ", b, (char) b);
if (++count == 8) {
System.out.println();
count = 0;
} else if (count % 2 == 0) {
System.out.print("| ");
}
}
System.out.println();
System.out.println("+++++++++++++++++++++++++++++");
}
public static void printPrettyDecimalUnsignedBytes(ByteBuffer bytes) {
bytes = bytes.slice();
System.out.println("-----------------------------");
int count = 0;
for (int x = 0; x < bytes.limit(); ++x) {
System.out.printf("%02X(%d) ", bytes.get(x), Byte.toUnsignedInt(bytes.get(x)));
if (++count == 8) {
System.out.println();
count = 0;
} else if (count % 2 == 0) {
System.out.print("| ");
}
}
System.out.println();
System.out.println("+++++++++++++++++++++++++++++");
}
public static Packet getResponse(final Packet request) throws Exception {
final SocketFactory socketFactory = SocketFactory.getDefault();
final Socket upstream = socketFactory.createSocket("8.8.4.4", 53);
//final SSLContext sslContext = Java7Pinning.forPin("SHA256:c22904de360003a8d0997613affadb1de10f982efc750c196d0a7a59daec784b");
//final SocketFactory socketFactory = sslContext.getSocketFactory();
//final Socket upstream = socketFactory.createSocket("89.233.43.71", 853);
//final Socket ssl = new SSL("8.8.4.4", 53);
final Packet response;
try (InputStream upIs = upstream.getInputStream();
DataInputStream upDis = new DataInputStream(upIs);
OutputStream upOs = upstream.getOutputStream();
DataOutputStream upDos = new DataOutputStream(upOs)) {
writeTcpPacket(request, upDos);
upDos.flush();
response = readTcpPacket(upDis);
}
return response;
}
public static Packet getHttpResponse(final Packet request) throws Exception {
final URL url = new URL("https://dns.google.com/experimental?ct");
final HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
//final SSLContext sslContext = Java7Pinning.forPin("SHA256:c96d45b587a9230a50185ddd25ff36fd23bee886c91a5133d8bd82d9c4f0b676");
//final SSLSocketFactory socketFactory = sslContext.getSocketFactory();
//conn.setSSLSocketFactory(socketFactory);
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/dns-udpwireformat");
conn.setRequestProperty("Accept", "application/dns-udpwireformat");
try (OutputStream os = conn.getOutputStream()) {
os.write(request.getBuf().array());
os.flush();
try (InputStream is = conn.getInputStream();
DataInputStream dis = new DataInputStream(is);) {
final int responseCode = conn.getResponseCode();
System.out.println("responseCode: " + responseCode);
final int contentLength = conn.getContentLength();
System.out.println("contentLength: " + contentLength);
return readPacket(contentLength, dis);
}
}
}
public static byte[] getBytesFromInputStream(InputStream is) throws IOException {
try (ByteArrayOutputStream os = new ByteArrayOutputStream();) {
final byte[] buffer = new byte[2048];
for (int len; (len = is.read(buffer)) != -1; )
os.write(buffer, 0, len);
os.flush();
return os.toByteArray();
}
}
public static void maine(String[] args) throws Throwable {
// sync udp
final DatagramSocket ss = new DatagramSocket(5555);
final DatagramPacket request = new DatagramPacket(new byte[512], 512);
final InetAddress upSrv = InetAddress.getByName("8.8.4.4");
final DatagramSocket upstream = ss;//new DatagramSocket();
//upstream.connect(upSrv, 53);
while (!ss.isClosed()) {
ss.receive(request);
System.out.println("got packet");
System.out.println(new Packet(ByteBuffer.wrap(request.getData(), request.getOffset(), request.getLength()).slice()));
debugPacket(request.getData());
final InetAddress old = request.getAddress();
final int oldPort = request.getPort();
request.setAddress(upSrv);
request.setPort(53);
upstream.send(request);
System.out.println("sent packet");
upstream.receive(request);
System.out.println("got packet 2");
request.setAddress(old);
request.setPort(oldPort);
ss.send(request);
System.out.println("sent packet");
}
// sync tcp with debug
if (false)
try (FileInputStream request = new FileInputStream("test.request");
FileInputStream response = new FileInputStream("test.resolve");
) {
System.out.println("request: ");
debugPacket(getBytesFromInputStream(request));
System.out.println("resolve: ");
debugPacket(getBytesFromInputStream(response));
// just testing
return;
} catch (FileNotFoundException e) {
// ignore, start normal
}
//if(true) return;
final ServerSocket ss = new ServerSocket(5555);
while (!ss.isClosed()) {
final Socket s = ss.accept();
System.out.println("got socket");
try (InputStream is = s.getInputStream();
DataInputStream dis = new DataInputStream(is);
OutputStream os = s.getOutputStream();
DataOutputStream dos = new DataOutputStream(os)) {
final Packet request = readTcpPacket(dis);
final int requestId = request.getId();
request.setId(0);
try (FileOutputStream fos = new FileOutputStream("test.request")) {
fos.write(request.getBuf().array());
}
System.out.println("request: " + request);
//final Packet resolve = getResponse(request);
final Packet response = getHttpResponse(request);
try (FileOutputStream fos = new FileOutputStream("test.resolve")) {
fos.write(response.getBuf().array());
}
System.out.println("resolve: " + response);
//debugPacket(resolve);
response.setId(requestId);
writeTcpPacket(response, dos);
dos.flush();
}
}
}
*/
}