/******************************************************************************* * 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 staticContent.framework.infoService; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.util.HashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import staticContent.framework.clock.Clock; import staticContent.framework.config.Settings; import staticContent.framework.controller.routing.RoutingModeInfoServiceController; import staticContent.framework.launcher.CommandLineParameters; import staticContent.framework.routing.MixList; import staticContent.framework.util.Util; public class InfoServiceServer { // TODO: ssl // TODO: sign data stored by mixes // TODO: pki private boolean LOCAL_MODE_ON; private boolean DEBUG_MODE_ON; private boolean DUPLEX_ON; private int NUMBER_OF_MIXES; private int PORT; private int BACKLOG; private String ADDRESS; private AtomicInteger clientIdCounter = new AtomicInteger(0); private AtomicInteger mixPort = new AtomicInteger(23301); private AtomicBoolean addressExchangePhaseFinished = new AtomicBoolean(false); private AtomicBoolean registrationPhaseFinished = new AtomicBoolean(false); private AtomicBoolean initPhaseFinished = new AtomicBoolean(false); private AtomicBoolean beginPhaseFinished = new AtomicBoolean(false); private int addressesReceived = 0; private int registeredMixes = 0; private int initializedMixes = 0; private int readyMixes = 0; private ServerSocket serverSocket; private HashMap<Integer, HashMap<String, byte[]>> mixData = new HashMap<Integer, HashMap<String, byte[]>>(); private HashMap<Integer, HashMap<String, byte[]>> clientData = new HashMap<Integer, HashMap<String, byte[]>>(); private HashMap<String, byte[]> anonData = new HashMap<String, byte[]>(); private Settings settings; private RoutingModeInfoServiceController routingPlugin; public InfoServiceServer(CommandLineParameters commandLineParameters) { settings = commandLineParameters.generateSettingsObject(); ProtocolPrimitives.DEBUG = settings.getPropertyAsBoolean("IS_DISPLAY_TRANSACTIONS"); this.LOCAL_MODE_ON = settings.getPropertyAsBoolean("GLOBAL_LOCAL_MODE_ON"); if (!LOCAL_MODE_ON) System.err.println("WARNING: LOCAL_MODE is set to FALSE; Mixes and Information Service will be available via Network; Only safe for trusted networks!"); this.DEBUG_MODE_ON = settings.getPropertyAsBoolean("GLOBAL_DEBUG_MODE_ON"); this.DUPLEX_ON = settings.getPropertyAsBoolean("GLOBAL_IS_DUPLEX"); this.NUMBER_OF_MIXES = settings.getPropertyAsInt("GLOBAL_NUMBER_OF_MIXES"); this.PORT = settings.getPropertyAsInt("GLOBAL_INFO_SERVICE_PORT"); this.ADDRESS = settings.getProperty("GLOBAL_INFO_SERVICE_ADDRESS"); this.BACKLOG = settings.getPropertyAsInt("IS_BACKLOG"); this.routingPlugin = new RoutingModeInfoServiceController(settings, new Clock(settings)); begin(); } /** * Comment * * @param args Not used. */ public static void main(String[] args) { new InfoServiceServer(new CommandLineParameters(args)); } private void begin() { try { if (LOCAL_MODE_ON) serverSocket = new ServerSocket(PORT, BACKLOG, InetAddress.getByName("localhost")); else if (ADDRESS.equalsIgnoreCase("AUTO")) serverSocket = new ServerSocket(PORT, BACKLOG, InetAddress.getLocalHost()); else serverSocket = new ServerSocket(PORT, BACKLOG, InetAddress.getByName(ADDRESS)); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(""); } new Thread( new Runnable() { public void run() { acceptConnections(); } } ).start(); } private void acceptConnections() { System.out.println("Information Service up on " +serverSocket.getLocalSocketAddress()); while(true) { try { Socket connectionSocket = serverSocket.accept(); new InfoConnectionHandler(connectionSocket); } catch (IOException e) { e.printStackTrace(); } } } private class InfoConnectionHandler extends Thread { private Socket socket; private InputStream inputStream; private OutputStream outputStream; public InfoConnectionHandler(Socket s) { this.socket = s; try { this.socket.setKeepAlive(true); this.inputStream = s.getInputStream(); this.outputStream = s.getOutputStream(); } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } start(); } @Override public void run() { System.out.println("InfoServiceServer: new connection from client"); // TODO while (true) { try { String command = ProtocolPrimitives.receiveString(inputStream); if (command == null) { socket.close(); return; } else if (command.equals("REGISTER_MIX")) REGISTER_AS_MIX(socket, outputStream, inputStream); else if (command.equals("REGISTER_CLIENT")) REGISTER_AS_CLIENT(outputStream, inputStream); else if (command.equals("GET_VALUE_FROM_MIX")) GET_VALUE_FROM_MIX(outputStream, inputStream); else if (command.equals("GET_VALUE_FROM_CLIENT")) GET_VALUE_FROM_CLIENT(outputStream, inputStream); else if (command.equals("GET_VALUE_FROM_ALL_MIXES")) GET_VALUE_FROM_ALL_MIXES(outputStream, inputStream); else if (command.equals("GET_VALUE")) GET_VALUE(outputStream, inputStream); else if (command.equals("POST_VALUE")) POST_VALUE(outputStream, inputStream); else if (command.equals("POST_VALUE_AS_MIX")) POST_VALUE_AS_MIX(outputStream, inputStream); else if (command.equals("POST_VALUE_AS_CLIENT")) POST_VALUE_AS_CLIENT(outputStream, inputStream); else if (command.equals("GET_MIX_LIST")) GET_MIX_LIST(outputStream, inputStream); else if (command.equals("GET_NUMBER_OF_MIXES")) GET_NUMBER_OF_MIXES(outputStream); else if (command.equals("SUGGEST_MIX_PORT")) SUGGEST_MIX_PORT(outputStream); else if (command.equals("DEBUG_MODE_ON")) DEBUG_MODE_ON(outputStream); else if (command.equals("LOCAL_MODE_ON")) LOCAL_MODE_ON(outputStream); else if (command.equals("DUPLEX_ON")) DUPLEX_ON(outputStream); else if (command.equals("WAIT_FOR_END_OF_ADDRESS_EXCHANGE_PHASE")) WAIT_FOR_END_OF_ADDRESS_EXCHANGE_PHASE(outputStream, inputStream); else if (command.equals("WAIT_FOR_END_OF_REGISTRATION_PHASE")) WAIT_FOR_END_OF_REGISTRATION_PHASE(outputStream, inputStream); else if (command.equals("WAIT_FOR_END_OF_INITIALIZATION_PHASE")) WAIT_FOR_END_OF_INITIALIZATION_PHASE(outputStream, inputStream); else if (command.equals("WAIT_FOR_END_OF_BEGIN_PHASE")) WAIT_FOR_END_OF_BEGIN_PHASE(outputStream, inputStream); else if (command.equals("WAIT_TILL_MIXES_ARE_UP")) WAIT_TILL_MIXES_ARE_UP(outputStream, inputStream); else if (command.equals("DISCONNECT")) { socket.close(); return; } else throw new Exception("received unknown command: " +command); } catch (Exception e) { e.printStackTrace(); try {socket.close();} catch (IOException ex) {} return; // TODO: continue; } } } } private void REGISTER_AS_MIX(Socket socket, OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: REGISTER_AS_MIX()"); int id; HashMap<String, byte[]> data; synchronized (mixData) { id = routingPlugin.assignMixIdServerSide(socket); data = new HashMap<String, byte[]>(); mixData.put(id, data); } if (ProtocolPrimitives.DEBUG) System.out.println("server: REGISTER_AS_MIX(): result: " +id); ProtocolPrimitives.sendInt(outputStream, id); outputStream.flush(); } public static int client_REGISTER_AS_MIX(RoutingModeInfoServiceController infoServiceRoutingPlugIn, Socket socket, OutputStream outputStream, InputStream inputStream) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("int client_REGISTER_AS_MIX"); ProtocolPrimitives.sendString(outputStream, "REGISTER_MIX"); outputStream.flush(); infoServiceRoutingPlugIn.assignMixIdServerSide(socket); int id = ProtocolPrimitives.receiveInt(inputStream); if (ProtocolPrimitives.DEBUG) System.out.println("int request_REGISTER_AS_MIX(): result: " +id); return id; } private void REGISTER_AS_CLIENT(OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: REGISTER_AS_CLIENT()"); int id; HashMap<String, byte[]> data; synchronized (clientData) { id = clientIdCounter.getAndIncrement(); data = new HashMap<String, byte[]>(); clientData.put(id, data); } if (ProtocolPrimitives.DEBUG) System.out.println("server: REGISTER_AS_CLIENT(): result: " +id); ProtocolPrimitives.sendInt(outputStream, id); outputStream.flush(); } public static int client_REGISTER_AS_CLIENT(OutputStream outputStream, InputStream inputStream) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("int client_REGISTER_AS_CLIENT"); ProtocolPrimitives.sendString(outputStream, "REGISTER_CLIENT"); outputStream.flush(); int id = ProtocolPrimitives.receiveInt(inputStream); if (ProtocolPrimitives.DEBUG) System.out.println("int client_REGISTER_AS_CLIENT(): result: " +id); return id; } private void LOCAL_MODE_ON(OutputStream outputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: LOCAL_MODE_ON() (" +LOCAL_MODE_ON +")"); ProtocolPrimitives.sendBoolean(outputStream, LOCAL_MODE_ON); outputStream.flush(); } public static boolean client_is_LOCAL_MODE_ON(OutputStream outputStream, InputStream inputStream) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("boolean client_is_LOCAL_MODE_ON"); ProtocolPrimitives.sendString(outputStream, "LOCAL_MODE_ON"); outputStream.flush(); boolean result = ProtocolPrimitives.receiveBoolean(inputStream); if (ProtocolPrimitives.DEBUG) System.out.println("boolean client_is_LOCAL_MODE_ON: result: " +result); return result; } private void DEBUG_MODE_ON(OutputStream outputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: DEBUG_MODE_ON() (" +DEBUG_MODE_ON +")"); ProtocolPrimitives.sendBoolean(outputStream, DEBUG_MODE_ON); outputStream.flush(); } public static boolean client_is_DEBUG_MODE_ON(OutputStream outputStream, InputStream inputStream) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("boolean client_is_DEBUG_MODE_ON"); ProtocolPrimitives.sendString(outputStream, "DEBUG_MODE_ON"); outputStream.flush(); boolean result = ProtocolPrimitives.receiveBoolean(inputStream); if (ProtocolPrimitives.DEBUG) System.out.println("boolean client_is_DEBUG_MODE_ON: result: " +result); return result; } private void DUPLEX_ON(OutputStream outputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: DUPLEX_ON() (" +DUPLEX_ON +")"); ProtocolPrimitives.sendBoolean(outputStream, DUPLEX_ON); outputStream.flush(); } public static boolean client_is_DUPLEX_ON(OutputStream outputStream, InputStream inputStream) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("boolean client_is_DUPLEX_ON"); ProtocolPrimitives.sendString(outputStream, "DUPLEX_ON"); outputStream.flush(); boolean result = ProtocolPrimitives.receiveBoolean(inputStream); if (ProtocolPrimitives.DEBUG) System.out.println("boolean client_is_DUPLEX_ON: result: " +result); return result; } private void SUGGEST_MIX_PORT(OutputStream outputStream) throws Exception { int port = mixPort.getAndIncrement(); if (ProtocolPrimitives.DEBUG) System.out.println("server: SUGGEST_MIX_PORT(): " +port); ProtocolPrimitives.sendInt(outputStream, port); outputStream.flush(); } public static int client_SUGGEST_MIX_PORT(OutputStream outputStream, InputStream inputStream) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("int client_SUGGEST_MIX_PORT"); ProtocolPrimitives.sendString(outputStream, "SUGGEST_MIX_PORT"); outputStream.flush(); int result = ProtocolPrimitives.receiveInt(inputStream); if (ProtocolPrimitives.DEBUG) System.out.println("int client_SUGGEST_MIX_PORT: result: " +result); return result; } private void GET_NUMBER_OF_MIXES(OutputStream outputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: GET_NUMBER_OF_MIXES(): " +NUMBER_OF_MIXES); ProtocolPrimitives.sendInt(outputStream, NUMBER_OF_MIXES); outputStream.flush(); } public static int client_GET_NUMBER_OF_MIXES(OutputStream outputStream, InputStream inputStream) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("int GET_NUMBER_OF_MIXES"); ProtocolPrimitives.sendString(outputStream, "GET_NUMBER_OF_MIXES"); outputStream.flush(); int result = ProtocolPrimitives.receiveInt(inputStream); if (ProtocolPrimitives.DEBUG) System.out.println("int GET_NUMBER_OF_MIXES: result: " +result); return result; } private boolean POST_VALUE_AS_MIX(OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: POST_VALUE_AS_MIX()"); int mixId = ProtocolPrimitives.receiveInt(inputStream); String key = ProtocolPrimitives.receiveString(inputStream); byte[] value = ProtocolPrimitives.receiveByteArray(inputStream); synchronized (mixData) { HashMap<String, byte[]> recordForMix = mixData.get(mixId); if (recordForMix == null || key == null || key.equals("") || value == null || value.length == 0) return false; recordForMix.put(key, value); if (ProtocolPrimitives.DEBUG) System.out.println("int POST_VALUE_AS_MIX: result: " +mixId +", " +key +", " +Util.md5(value)); return true; } } public static void client_POST_VALUE_AS_MIX(OutputStream outputStream, InputStream inputStream, int mixId, String key, byte[] value) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("void client_POST_VALUE_AS_MIX("+mixId +", "+key +", " +Util.md5(value) +")"); ProtocolPrimitives.sendString(outputStream, "POST_VALUE_AS_MIX"); ProtocolPrimitives.sendInt(outputStream, mixId); ProtocolPrimitives.sendString(outputStream, key); ProtocolPrimitives.sendByteArray(outputStream, value); outputStream.flush(); } private void POST_VALUE(OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: POST_VALUE()"); String key = ProtocolPrimitives.receiveString(inputStream); byte[] value = ProtocolPrimitives.receiveByteArray(inputStream); synchronized (anonData) { anonData.put(key, value); if (ProtocolPrimitives.DEBUG) System.out.println("int POST_VALUE: result: " +key +", " +Util.md5(value)); } } public static void client_POST_VALUE(OutputStream outputStream, InputStream inputStream, String key, byte[] value) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("void client_POST_VALUE("+key +", " +Util.md5(value) +")"); ProtocolPrimitives.sendString(outputStream, "POST_VALUE"); ProtocolPrimitives.sendString(outputStream, key); ProtocolPrimitives.sendByteArray(outputStream, value); outputStream.flush(); } private boolean POST_VALUE_AS_CLIENT(OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: POST_VALUE_AS_CLIENT()"); int clientId = ProtocolPrimitives.receiveInt(inputStream); String key = ProtocolPrimitives.receiveString(inputStream); byte[] value = ProtocolPrimitives.receiveByteArray(inputStream); synchronized (clientData) { HashMap<String, byte[]> recordForClient = clientData.get(clientId); if (recordForClient == null || key == null || key.equals("") || value == null || value.length == 0) return false; recordForClient.put(key, value); if (ProtocolPrimitives.DEBUG) System.out.println("int POST_VALUE_AS_CLIENT: result: " +clientId +", " +key +", " +Util.md5(value)); return true; } } public static void client_POST_VALUE_AS_CLIENT(OutputStream outputStream, InputStream inputStream, int clientId, String key, byte[] value) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("void client_POST_VALUE_AS_CLIENT("+clientId +", "+key +", " +Util.md5(value) +")"); ProtocolPrimitives.sendString(outputStream, "POST_VALUE_AS_CLIENT"); ProtocolPrimitives.sendInt(outputStream, clientId); ProtocolPrimitives.sendString(outputStream, key); ProtocolPrimitives.sendByteArray(outputStream, value); outputStream.flush(); } public boolean GET_VALUE_FROM_MIX(OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: GET_VALUE_FROM_MIX()"); int mixId = ProtocolPrimitives.receiveInt(inputStream); String key = ProtocolPrimitives.receiveString(inputStream); boolean success = true; byte[] data; synchronized (mixData) { HashMap<String, byte[]> recordForMix = mixData.get(mixId); if (recordForMix == null || (data = recordForMix.get(key)) == null) { success = false; throw new RuntimeException(key); } } if (ProtocolPrimitives.DEBUG) System.out.println("GET_VALUE_FROM_MIX() result: " +Util.md5(data)); ProtocolPrimitives.sendByteArray(outputStream, data); outputStream.flush(); return success; } public static byte[] client_GET_VALUE_FROM_MIX(OutputStream outputStream, InputStream inputStream, int mixId, String key) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("byte[] client_GET_VALUE_FROM_MIX("+mixId +", "+key +")"); ProtocolPrimitives.sendString(outputStream, "GET_VALUE_FROM_MIX"); ProtocolPrimitives.sendInt(outputStream, mixId); ProtocolPrimitives.sendString(outputStream, key); outputStream.flush(); byte[] result = ProtocolPrimitives.receiveByteArray(inputStream); if (ProtocolPrimitives.DEBUG) System.out.println("byte[] client_GET_VALUE_FROM_MIX: result: " +Util.md5(result)); return result; } public boolean GET_VALUE(OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: GET_VALUE()"); String key = ProtocolPrimitives.receiveString(inputStream); byte[] data; synchronized (anonData) { data = anonData.get(key); if (data == null) return false; } if (ProtocolPrimitives.DEBUG) System.out.println("GET_VALUE() result: " +Util.md5(data)); ProtocolPrimitives.sendByteArray(outputStream, data); outputStream.flush(); return true; } public static byte[] client_GET_VALUE(OutputStream outputStream, InputStream inputStream, String key) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("byte[] client_GET_VALUE("+key +")"); ProtocolPrimitives.sendString(outputStream, "GET_VALUE"); ProtocolPrimitives.sendString(outputStream, key); outputStream.flush(); byte[] result = ProtocolPrimitives.receiveByteArray(inputStream); if (ProtocolPrimitives.DEBUG) System.out.println("byte[] client_GET_VALUE: result: " +Util.md5(result)); return result; } public boolean GET_VALUE_FROM_CLIENT(OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: GET_VALUE_FROM_CLIENT()"); int mixId = ProtocolPrimitives.receiveInt(inputStream); String key = ProtocolPrimitives.receiveString(inputStream); boolean success = true; byte[] data; synchronized (clientData) { HashMap<String, byte[]> recordForClient = clientData.get(mixId); if (recordForClient == null || (data = recordForClient.get(key)) == null) { success = false; throw new RuntimeException(key); } } if (ProtocolPrimitives.DEBUG) System.out.println("GET_VALUE_FROM_CLIENT() result: " +Util.md5(data)); ProtocolPrimitives.sendByteArray(outputStream, data); outputStream.flush(); return success; } public static byte[] client_GET_VALUE_FROM_CLIENT(OutputStream outputStream, InputStream inputStream, int clientId, String key) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("byte[] client_GET_VALUE_FROM_CLIENT("+clientId +", "+key +")"); ProtocolPrimitives.sendString(outputStream, "GET_VALUE_FROM_CLIENT"); ProtocolPrimitives.sendInt(outputStream, clientId); ProtocolPrimitives.sendString(outputStream, key); outputStream.flush(); byte[] result = ProtocolPrimitives.receiveByteArray(inputStream); if (ProtocolPrimitives.DEBUG) System.out.println("byte[] client_GET_VALUE_FROM_CLIENT: result: " +Util.md5(result)); return result; } public boolean GET_VALUE_FROM_ALL_MIXES(OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: GET_VALUE_FROM_ALL_MIXES()"); String key = ProtocolPrimitives.receiveString(inputStream); ProtocolPrimitives.sendInt(outputStream, NUMBER_OF_MIXES); outputStream.flush(); boolean success = true; for (int i=0; i<NUMBER_OF_MIXES; i++) { byte[] data; synchronized (mixData) { HashMap<String, byte[]> recordForMix = mixData.get(i); if (recordForMix == null || (data = recordForMix.get(key)) == null) { success = false; throw new RuntimeException(key +"; "+i); } } ProtocolPrimitives.sendByteArray(outputStream, data); } outputStream.flush(); return success; } public static byte[][] client_GET_VALUE_FROM_ALL_MIXES(OutputStream outputStream, InputStream inputStream, String key) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("byte[] client_GET_VALUE_FROM_ALL_MIXES("+key +")"); ProtocolPrimitives.sendString(outputStream, "GET_VALUE_FROM_ALL_MIXES"); ProtocolPrimitives.sendString(outputStream, key); outputStream.flush(); int numberOfMixes = ProtocolPrimitives.receiveInt(inputStream); byte[][] result = new byte[numberOfMixes][]; for (int i=0; i<numberOfMixes; i++) { result[i] = ProtocolPrimitives.receiveByteArray(inputStream); } return result; } public void GET_MIX_LIST(OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: GET_MIX_LIST()"); synchronized (mixData) { ProtocolPrimitives.sendInt(outputStream, NUMBER_OF_MIXES); for (int i=0; i<NUMBER_OF_MIXES; i++) { // data for each mix ProtocolPrimitives.sendInt(outputStream, i); // mixid ProtocolPrimitives.sendByteArray(outputStream, mixData.get(i).get("ADDRESS")); // address ProtocolPrimitives.sendInt(outputStream, Util.byteArrayToInt(mixData.get(i).get("PORT"))); // port } } outputStream.flush(); } public static MixList client_GET_MIX_LIST(OutputStream outputStream, InputStream inputStream) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("byte[] GET_MIX_LIST()"); ProtocolPrimitives.sendString(outputStream, "GET_MIX_LIST"); outputStream.flush(); MixList mixList = new MixList(); mixList.numberOfMixes = ProtocolPrimitives.receiveInt(inputStream); mixList.mixIDs = new int[mixList.numberOfMixes]; mixList.addresses = new InetAddress[mixList.numberOfMixes]; mixList.ports = new int[mixList.numberOfMixes]; for (int i=0; i<mixList.numberOfMixes; i++) { mixList.mixIDs[i] = ProtocolPrimitives.receiveInt(inputStream); mixList.addresses[i] = InetAddress.getByAddress(ProtocolPrimitives.receiveByteArray(inputStream)); mixList.ports[i] = ProtocolPrimitives.receiveInt(inputStream); } return mixList; } public static void client_WAIT_FOR_END_OF_ADDRESS_EXCHANGE_PHASE(OutputStream outputStream, InputStream inputStream) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("void client_WAIT_FOR_END_OF_ADDRESS_EXCHANGE_PHASE()"); ProtocolPrimitives.sendString(outputStream, "WAIT_FOR_END_OF_ADDRESS_EXCHANGE_PHASE"); String result = ProtocolPrimitives.receiveString(inputStream); if (!result.equals("ADDRESS_EXCHANGE_PHASE_DONE")) throw new RuntimeException("received wrong result!"); } public void WAIT_FOR_END_OF_ADDRESS_EXCHANGE_PHASE(OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: WAIT_FOR_END_OF_ADDRESS_EXCHANGE_PHASE()"); synchronized(addressExchangePhaseFinished) { addressesReceived++; if (addressesReceived >= NUMBER_OF_MIXES) { System.out.println("InfoService: address exchange phase finished"); addressExchangePhaseFinished.set(true); addressExchangePhaseFinished.notifyAll(); /*synchronized (eventListeners) { // TODO for (EipEventListener eipel:eventListeners) eipel.registrationPhaseFinished(); }*/ } else { while (addressExchangePhaseFinished.get() == false) { try { addressExchangePhaseFinished.wait(); } catch (InterruptedException e) { e.printStackTrace(); continue; } } } } ProtocolPrimitives.sendString(outputStream, "ADDRESS_EXCHANGE_PHASE_DONE"); outputStream.flush(); } public void WAIT_FOR_END_OF_REGISTRATION_PHASE(OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: WAIT_FOR_END_OF_REGISTRATION_PHASE()"); synchronized(registrationPhaseFinished) { registeredMixes++; if (registeredMixes >= NUMBER_OF_MIXES) { System.out.println("InfoService: registration phase finished"); registrationPhaseFinished.set(true); registrationPhaseFinished.notifyAll(); /*synchronized (eventListeners) { // TODO for (EipEventListener eipel:eventListeners) eipel.registrationPhaseFinished(); }*/ } else { while (registrationPhaseFinished.get() == false) { try { registrationPhaseFinished.wait(); } catch (InterruptedException e) { e.printStackTrace(); continue; } } } } ProtocolPrimitives.sendString(outputStream, "REGISTRATION_PHASE_DONE"); outputStream.flush(); } public static void client_WAIT_FOR_END_OF_REGISTRATION_PHASE(OutputStream outputStream, InputStream inputStream) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("void client_WAIT_FOR_END_OF_REGISTRATION_PHASE()"); ProtocolPrimitives.sendString(outputStream, "WAIT_FOR_END_OF_REGISTRATION_PHASE"); String result = ProtocolPrimitives.receiveString(inputStream); if (!result.equals("REGISTRATION_PHASE_DONE")) throw new RuntimeException("received wrong result!"); } public void WAIT_FOR_END_OF_INITIALIZATION_PHASE(OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: WAIT_FOR_END_OF_INITIALIZATION_PHASE()"); synchronized(initPhaseFinished) { initializedMixes++; if (initializedMixes >= NUMBER_OF_MIXES) { System.out.println("InfoService: initialization phase finished"); initPhaseFinished.set(true); initPhaseFinished.notifyAll(); /*synchronized (eventListeners) { // TODO for (EipEventListener eipel:eventListeners) eipel.registrationPhaseFinished(); }*/ } else { while (this.initPhaseFinished.get() == false) { try { initPhaseFinished.wait(); } catch (InterruptedException e) { e.printStackTrace(); continue; } } } } ProtocolPrimitives.sendString(outputStream, "INITIALIZATION_PHASE_DONE"); outputStream.flush(); } public static void client_WAIT_FOR_END_OF_INITIALIZATION_PHASE(OutputStream outputStream, InputStream inputStream) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("void client_WAIT_FOR_END_OF_INITIALIZATION_PHASE()"); ProtocolPrimitives.sendString(outputStream, "WAIT_FOR_END_OF_INITIALIZATION_PHASE"); String result = ProtocolPrimitives.receiveString(inputStream); if (!result.equals("INITIALIZATION_PHASE_DONE")) throw new RuntimeException("received wrong result!"); } public void WAIT_FOR_END_OF_BEGIN_PHASE(OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: WAIT_FOR_END_OF_BEGIN_PHASE()"); synchronized(beginPhaseFinished) { readyMixes++; if (readyMixes >= NUMBER_OF_MIXES) { System.out.println("InfoService: all mixes are up (begin phase finished)"); beginPhaseFinished.set(true); beginPhaseFinished.notifyAll(); /*synchronized (eventListeners) { // TODO for (EipEventListener eipel:eventListeners) eipel.registrationPhaseFinished(); }*/ } else { while (beginPhaseFinished.get() == false) { try { beginPhaseFinished.wait(); } catch (InterruptedException e) { e.printStackTrace(); continue; } } } } ProtocolPrimitives.sendString(outputStream, "BEGIN_PHASE_DONE"); outputStream.flush(); } public static void client_WAIT_FOR_END_OF_BEGIN_PHASE(OutputStream outputStream, InputStream inputStream) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("void client_WAIT_FOR_END_OF_BEGIN_PHASE()"); ProtocolPrimitives.sendString(outputStream, "WAIT_FOR_END_OF_BEGIN_PHASE"); String result = ProtocolPrimitives.receiveString(inputStream); if (!result.equals("BEGIN_PHASE_DONE")) throw new RuntimeException("received wrong result!"); } public void WAIT_TILL_MIXES_ARE_UP(OutputStream outputStream, InputStream inputStream) throws Exception { if (ProtocolPrimitives.DEBUG) System.out.println("server: WAIT_TILL_MIXES_ARE_UP()"); synchronized(beginPhaseFinished) { while (beginPhaseFinished.get() == false) { try { beginPhaseFinished.wait(); } catch (InterruptedException e) { e.printStackTrace(); continue; } } } ProtocolPrimitives.sendString(outputStream, "MIXES_ARE_UP"); outputStream.flush(); } public static void client_WAIT_TILL_MIXES_ARE_UP(OutputStream outputStream, InputStream inputStream) throws UnsupportedEncodingException, IOException { if (ProtocolPrimitives.DEBUG) System.out.println("void client_WAIT_TILL_MIXES_ARE_UP()"); ProtocolPrimitives.sendString(outputStream, "WAIT_TILL_MIXES_ARE_UP"); String result = ProtocolPrimitives.receiveString(inputStream); if (!result.equals("MIXES_ARE_UP")) throw new RuntimeException("received wrong result!"); } public void localWaitTillMixesAreUp() throws IOException { if (ProtocolPrimitives.DEBUG) System.out.println("server: localWaitTillMixesAreUp()"); synchronized(beginPhaseFinished) { while (beginPhaseFinished.get() == false) { try { beginPhaseFinished.wait(); } catch (InterruptedException e) { e.printStackTrace(); continue; } } } } }