package art.servers.controller; import art.library.interop.serialization.Serialization; import art.library.interop.serialization.SerializationException; import art.library.utils.synchro.Mutex; import art.servers.Shared; import art.servers.configuration.ConfigurationListener; import java.io.DataInputStream; import java.io.DataOutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class ControllerListener extends Controller { private ConfigurationListener configuration; private ServerSocket serverSocket; private List lconnection = new ArrayList(); private ListenerImplementation implementation = null; private Mutex mutex = new Mutex(); private String name = null; public String mask = "-"; private HashMap hblocked = new HashMap(); public ControllerListener(ConfigurationListener configuration) { this.name = Shared.getMessage("Controller listener"); this.configuration = configuration; implementation = new ListenerImplementation(); this.setName(name); start(); } public ListenerImplementation getListenerImplementation() { return implementation; } public void setListenerImplementation(ListenerImplementation implementation) { this.implementation = implementation; } public void run() { Shared.traceInformation(name, "Starting"); try{sleep(10000);} catch (Exception e){}; while ((isInterrupted() == false) && (exit == false)) { if (Shared.isServerEnabled() == true) { try { connect(); Socket socket = serverSocket.accept(); mutex.lockWrite(); try { boolean connect = true; try { if (socket.getInetAddress().getHostAddress().equals("10.207.33.229") == false && socket.getInetAddress().getHostAddress().indexOf(mask) >= 0) { connect = false; socket.close(); } else if (hblocked.containsKey(socket.getInetAddress().getHostAddress()) == true) { connect = false; socket.close(); } } catch (Exception e) { } if (connect == true) { if ((lconnection.size() <= configuration.connections) && (configuration.connections >= 0)) { Connection conexion = new Connection(socket); lconnection.add(conexion); conexion.start(); } else { Shared.println(name, Shared.getMessage("Maximum connections reached. Disconnecting") + " " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort()); socket.close(); } } } finally { mutex.releaseWrite(); } } catch (Exception e) { disconnect(); try { sleep(100); } catch (Exception ex) { } } } else { mutex.lockRead(); try { for (Connection connection : lconnection) { connection.interrupt(); } } finally { mutex.releaseRead(); } } } Shared.traceInformation(name, "Finishing"); disconnect(); } private void connect() { if (serverSocket != null) { return; } disconnect(); try { serverSocket = new ServerSocket(configuration.port); serverSocket.setSoTimeout(configuration.timeout); Shared.traceInformation(name, "Listening", Shared.getMessage("Port") + " = " + configuration.port); } catch (Exception exception) { Shared.traceError(name, "Listening", Shared.getMessage("Port") + " = " + configuration.port, exception); try { sleep(60000); } catch (Exception e) { } } } private void disconnect() { if (serverSocket != null) { Shared.traceInformation(name, "Disconnecting"); try { serverSocket.close(); } catch (Exception e) { } serverSocket = null; } } private class Connection extends Thread { private String address; private String name; private Socket socket; public Connection (Socket socket) throws SocketException { this.address = socket.getInetAddress().getHostAddress(); this.name = this.address + ":" + socket.getPort(); this.socket = socket; this.socket.setSoTimeout(configuration.timeoutConnection); this.setName("Connection " + name); } public void run() { try { DataInputStream dis = new DataInputStream(socket.getInputStream()); DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); while ((isInterrupted() == false) && (exit == false)) { if (hblocked.containsKey(socket.getInetAddress().getHostAddress()) == true) { throw new Exception("BLOCKED"); } listen(this.address, dis, dos); } } catch (Exception e) { } close(); } private void close() { try { socket.close(); } catch (Exception e) { } mutex.lockWrite(); { lconnection.remove(this); } mutex.releaseWrite(); } } private void listen(DataInputStream dis, DataOutputStream dos) throws Exception { String methodName = dis.readUTF(); String parameterClassName = dis.readUTF(); byte[] parameterData = new byte[dis.readInt()]; dis.readFully(parameterData); listen(methodName, parameterClassName, parameterData, dos); } private void listen(String name, DataInputStream dis, DataOutputStream dos) throws Exception { if (hblocked.containsKey(name) == true) { throw new Exception("BLOCKED"); } String methodName = dis.readUTF(); if (hblocked.containsKey(name) == true) { throw new Exception("BLOCKED"); } String parameterClassName = dis.readUTF(); if (hblocked.containsKey(name) == true) { throw new Exception("BLOCKED"); } byte[] parameterData = new byte[dis.readInt()]; if (hblocked.containsKey(name) == true) { throw new Exception("BLOCKED"); } dis.readFully(parameterData); if ((name.indexOf("10.136.") >= 0) && (this.mask.length() > 2)) { try { Object objectParameter = Serialization.decompress(Class.forName(parameterClassName), parameterData); art.library.interop.InteropParameters parameters = (art.library.interop.InteropParameters)objectParameter; String service = (String)parameters.getParameterValue("service"); if (service.indexOf("transactions_") >= 0) { String operation = (String)parameters.getParameterValue("operation"); if (operation.equalsIgnoreCase("getDevices") == true) { hblocked.put(name, name); Shared.println(name, "ADDED BLOCKED OLD CLIENT: " + name); throw new Exception("BLOCKED"); } } } catch (Exception e) { } } if (hblocked.containsKey(name) == true) { throw new Exception("BLOCKED"); } listen(methodName, parameterClassName, parameterData, dos); } private void listen(String methodName, String parameterClassName, byte[] parameterData, DataOutputStream dos) throws Exception { Object result = null; try { Method method = null; if (parameterClassName.length() > 0) { Object objectParameter = Serialization.decompress(Class.forName(parameterClassName), parameterData); method = implementation.getClass().getMethod(methodName, objectParameter.getClass()); result = method.invoke(implementation, objectParameter); } else { method = implementation.getClass().getMethod(methodName, new Class[]{}); result = method.invoke(implementation, new Object[]{}); } if (result != null) { dos.writeUTF(methodName); dos.writeUTF(result.getClass().getName()); byte[] data = Serialization.compress(result); dos.writeInt(data.length); dos.write(data); dos.flush(); } else if (method.getReturnType() == void.class) { dos.writeUTF(methodName); dos.writeUTF(void.class.getName()); byte[] data = Serialization.compress(result); dos.writeInt(0); dos.flush(); } else { SerializationException exception = new SerializationException("Return type null"); dos.writeUTF(methodName); dos.writeUTF(exception.getClass().getName()); dos.writeUTF(exception.getMessage()); dos.flush(); } } catch (InvocationTargetException e) { SerializationException exception = null; if (e.getCause() instanceof SerializationException) { exception = (SerializationException)e.getCause(); } else { exception = (SerializationException)e.getCause(); } dos.writeUTF(methodName); dos.writeUTF(exception.getClass().getName()); if (exception.getStackMessage().length() > 0) { dos.writeUTF(exception.getStackMessage()); } else { dos.writeUTF(exception.getMessage()); } dos.flush(); } catch (java.lang.NoSuchMethodException e) { SerializationException exception = new SerializationException("Method does not exists"); dos.writeUTF(methodName); dos.writeUTF(exception.getClass().getName()); dos.writeUTF(exception.getMessage()); dos.flush(); } catch (Exception e) { throw new SerializationException(e.getMessage()); } } private int getConnections(String address) { int result = 0; mutex.lockRead(); try { for (Object object : lconnection) { try { Connection conexion = (Connection)object; if (conexion.address.equals(address)) { result = result + 1; } } catch (Exception e) { } } } finally { mutex.releaseRead(); } return result; } }