/******************************************************************************* * gMix open source project - https://svs.informatik.uni-hamburg.de/gmix/ * Copyright (C) 2014 SVS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. *******************************************************************************/ package userGeneratedContent.testbedPlugIns.layerPlugIns.layer5application.encDNS_v0_001; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import staticContent.framework.EncDnsClient; import staticContent.framework.controller.Implementation; import staticContent.framework.interfaces.Layer1NetworkClient; import staticContent.framework.interfaces.Layer2RecodingSchemeClient; import staticContent.framework.interfaces.Layer5ApplicationClient; /** * local proxy for encdns (EncDNS-Proxy); stub resolver is supposed to * communicate with this component * * --- * * This is the EncDNS client proxy (also known as local proxy). It should be * executed on the client computer or at least be connected to it via a * trustworthy connection. The client proxy will encrypt standard DNS requests * sent to it by a stub resolver and pass the encrypted request on to the local * recursive nameserver. It will also decrypt the encrypted response received * from the local recursive nameserver and pass the decrypted standard DNS * response on to the stub resolver. * * This implementation currently supports UDP only. */ public class ClientPlugIn extends Implementation implements Layer5ApplicationClient { private DatagramSocket stubResolverSocket; // we will receive data from local client applications (via the stub resolver) via this socket private EncDnsClient owner; private Layer2RecodingSchemeClient layer2; private Layer1NetworkClient layer1; @Override public void constructor() { try { this.stubResolverSocket = new DatagramSocket(EncDnsClient.bindPort, EncDnsClient.bindAddr); System.out.println("listening on " +stubResolverSocket.getLocalAddress() +":" +stubResolverSocket.getLocalPort() +" for DNS queries"); } catch (IOException e) { System.err.println("Port busy! Exiting. (Try again as root user?)"); if(EncDnsClient.verbosity >= 1) { e.printStackTrace(); } System.exit(1); } this.owner = EncDnsClient.getInstance(); } @Override public void initialize() { this.layer2 = (Layer2RecodingSchemeClient) owner.recodingLayerClient.getImplementation(); this.layer1 = (Layer1NetworkClient) owner.networkLayerClient.getImplementation(); } @Override public void begin() { for (int i=0; i<EncDnsClient.threads; i++) new RequestReplyThread().start(); } public class RequestReplyThread extends Thread { @Override public void run() { byte[] rcvbytes = new byte[EncDnsClient.MAX_MSG_SIZE]; while (true) { DatagramPacket rcvPkt = new DatagramPacket(rcvbytes, rcvbytes.length); try { stubResolverSocket.receive(rcvPkt); } catch (IOException e) { System.err.println("Error receiving message from stub resolver"); if(EncDnsClient.verbosity >= 1) e.printStackTrace(); break; } if(EncDnsClient.verbosity >= 1) System.out.println("Received request from stub"); // Copy received standard DNS query into a byte[] byte[] payload = new byte[rcvPkt.getLength()]; System.arraycopy(rcvPkt.getData(), rcvPkt.getOffset(), payload, 0, rcvPkt.getLength()); EncDnsRequest request = new EncDnsRequest(rcvPkt.getAddress(), rcvPkt.getPort(), payload); request = (EncDnsRequest) layer2.applyLayeredEncryption(request); // skip layer 3 + 4... if (request == null || request.getByteMessage() == null) continue; layer1.sendMessage(request); EncDnsReply reply; //do { reply = (EncDnsReply) layer1.receiveReply(); // if you plan to edit this this class note that this reply is not necessarily the reply for the request sent above; it's just the next reply that arrived at layer 1 reply = (EncDnsReply) layer2.extractPayload(reply); DatagramPacket sendPacket = new DatagramPacket(reply.getByteMessage(), reply.getByteMessage().length, reply.stubResolverAdr, reply.stubResolverPort); try { stubResolverSocket.send(sendPacket); } catch (IOException e) { System.err.println("Error when sending response to stub resolver"); if(EncDnsClient.verbosity >= 1) e.printStackTrace(); } //} while (reply.getByteMessage()[3] == (byte) 0x82); // SERVFAIL -> try again } } } }