Compare commits

..

No commits in common. "master" and "master" have entirely different histories.

6 changed files with 37 additions and 97 deletions

View File

@ -34,7 +34,7 @@ public class Main {
if (args.length > 1) { if (args.length > 1) {
boolean isProxied = false; boolean isProxied = false;
if (args.length > 2) if (args.length > 2)
isProxied = args[2].equals("on"); isProxied = args[2].equals("on") ? true : false;
try { try {
server = new CrabServer(Integer.parseInt(args[1]), isProxied); server = new CrabServer(Integer.parseInt(args[1]), isProxied);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
@ -42,12 +42,15 @@ public class Main {
return; return;
} }
} else { } else {
System.err.println("Not enough arguments."); System.err.println("Now enough arguments.");
return; return;
} }
server.run(); server.run();
} }
default -> System.err.println("Unknown argument"); default -> {
System.err.println("Unknown argument");
return;
}
} }
} }

View File

@ -84,26 +84,16 @@ public class CrabClient implements Crab {
private void communicate() throws IOException { private void communicate() throws IOException {
Scanner scanner = new Scanner(System.in); Scanner scanner = new Scanner(System.in);
String message; String message;
boolean preserveScreen = false;
while (true) { while (true) {
if (!preserveScreen) { getLogs();
getLogs();
} else {
preserveScreen = false;
}
System.out.print("Enter a message (or type '/exit' to exit): "); System.out.print("Enter a message (or type '/exit' to exit): ");
message = scanner.nextLine(); message = scanner.nextLine();
if (message.equalsIgnoreCase("/exit")) { if (message.equalsIgnoreCase("/exit")) {
break; break;
} else if (message.equalsIgnoreCase("/info")) {
sendPacket(SERVER_INFO, "", true);
preserveScreen = true;
} else {
if (!message.isEmpty()) sendMessage(message);
} }
if (!message.isEmpty()) sendMessage(message);
} }
} }
@ -138,28 +128,7 @@ public class CrabClient implements Crab {
} case LOGS -> { } case LOGS -> {
byte[] bytes = socket.getInputStream().readNBytes(lastBufferLength); byte[] bytes = socket.getInputStream().readNBytes(lastBufferLength);
cache = new Logs(lastBufferLength, new String(bytes, StandardCharsets.UTF_8)); cache = new Logs(lastBufferLength, new String(bytes, StandardCharsets.UTF_8));
} case SERVER_INFO -> { } default -> {
InputStream input = socket.getInputStream();
int versionByte = input.read();
if (versionByte == -1) {
System.out.println("The server did not provide any information...");
return;
}
String protocolVersion;
switch (versionByte) {
case 0x01 -> protocolVersion = "RACv1";
case 0x02 -> protocolVersion = "RACv1.99";
case 0x03 -> protocolVersion = "RACv2";
default -> protocolVersion = "Unknown RAC version";
}
byte[] nameBytes = input.readAllBytes();
String serverName = new String(nameBytes, StandardCharsets.UTF_8);
System.out.println("\n\033[36mServer Information:\033[0m");
System.out.println("\033[33mProtocol:\033[0m " + protocolVersion);
System.out.println("\033[33mName:\033[0m " + serverName + "\n");
} }
} }
} }

View File

@ -7,5 +7,4 @@ public class PID {
public static final byte CACHED_LOGS = 0x02; public static final byte CACHED_LOGS = 0x02;
public static final byte AUTHENTICATED_MESSAGE = 0x02; public static final byte AUTHENTICATED_MESSAGE = 0x02;
public static final byte REGISTER = 0x03; public static final byte REGISTER = 0x03;
public static final byte SERVER_INFO = 0x69;
} }

View File

@ -6,10 +6,7 @@ import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.sql.SQLException;
import java.util.Scanner; import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CrabServer implements Crab { public class CrabServer implements Crab {
@ -18,9 +15,7 @@ public class CrabServer implements Crab {
private boolean isProxied = false; private boolean isProxied = false;
private int port; private int port;
private final Database db; private final Database db;
private Logs cache = new Logs(0, ""); public Logs cache = new Logs(0, "");
public static final byte RAC_VERSION = 0x02;
public final ExecutorService threadPool = Executors.newCachedThreadPool();
public CrabServer() { public CrabServer() {
this.db = new Database("data.db"); this.db = new Database("data.db");
@ -84,10 +79,12 @@ public class CrabServer implements Crab {
serverSocket = new ServerSocket(port); serverSocket = new ServerSocket(port);
} }
System.out.printf("Server successfully started! Listening on port %s.\nTo stop the server, type 'q'.\n", port); System.out.printf("Server successfully started! Listening on port %s.\nTo stop the server, type 'q'.\n", port);
threadPool.submit(new ServerCLI(scanner, this)); ServerCLI cli = new ServerCLI(scanner, this);
new Thread(cli).start();
while (!isStopped) { while (!isStopped) {
Socket socket = serverSocket.accept(); Socket socket = serverSocket.accept();
threadPool.submit(new ServerThread(socket, this)); ServerThread thread = new ServerThread(socket, this);
new Thread(thread).start();
} }
} }
@ -95,24 +92,13 @@ public class CrabServer implements Crab {
isStopped = true; isStopped = true;
try { try {
if (serverSocket != null) serverSocket.close(); if (serverSocket != null) serverSocket.close();
getDb().close();
} catch (IOException e) { } catch (IOException e) {
System.err.println("An error occured while closing the socket: " + e.getMessage()); System.err.println("An error occured while closing the socket: " + e.getMessage());
} catch (SQLException e) {
throw new RuntimeException(e);
} finally { } finally {
System.exit(0); System.exit(0);
} }
} }
public synchronized Logs getCache() {
return cache;
}
public synchronized void setCache(Logs cache) {
this.cache = cache;
}
public Database getDb() { public Database getDb() {
return db; return db;
} }

View File

@ -61,8 +61,4 @@ public class Database {
String logsString = s.toString(); String logsString = s.toString();
return new Logs(logsString.isEmpty() ? 0 : logsString.getBytes().length, logsString); return new Logs(logsString.isEmpty() ? 0 : logsString.getBytes().length, logsString);
} }
public void close() throws SQLException {
connection.close();
}
} }

View File

@ -47,7 +47,7 @@ public class ServerThread implements Runnable {
} }
if (Arrays.equals(readUntilChar(' '),"ROXY".getBytes())) { if (Arrays.equals(readUntilChar(' '),"ROXY".getBytes())) {
readUntilChar(' '); // proto readUntilChar(' '); // proto
byte[] source = readUntilChar(' '); byte source[] = readUntilChar(' ');
address = new String(source); address = new String(source);
readUntilChar(' '); // destination IP readUntilChar(' '); // destination IP
readUntilChar(' '); // source port readUntilChar(' '); // source port
@ -63,10 +63,10 @@ public class ServerThread implements Runnable {
return; return;
} }
PID = readPID(); PID = readPID();
if (PID.length == 0) { if (PID.length == 0) {
socket.close(); socket.close();
return; return;
} }
} }
switch (PID[0]) { switch (PID[0]) {
case MESSAGE -> { case MESSAGE -> {
@ -74,27 +74,18 @@ public class ServerThread implements Runnable {
Date date = new Date(); Date date = new Date();
String s = Sanitizer.sanitizeString(msg, true); String s = Sanitizer.sanitizeString(msg, true);
String newContent = server.getCache().content() + Sanitizer.formatMessage(date.getTime(), address, s); String newContent = server.cache.content() + Sanitizer.formatMessage(date.getTime(), address, s);
server.setCache(new Logs(newContent.getBytes().length, newContent)); server.cache = new Logs(newContent.getBytes().length, newContent);
server.threadPool.submit(new LogDBThread(date, address, msg));
new Thread(new LogDBThread(date, address, msg)).start();
} case LOGS_SIZE -> { } case LOGS_SIZE -> {
respond(String.valueOf(server.getCache().sizeInBytes())); respond(String.valueOf(server.cache.sizeInBytes()));
byte[] logPID = readPID(); byte[] logPID = readPID();
if (logPID.length == 0) { if (logPID.length == 0) {
socket.close(); socket.close();
return; return;
} }
sendLogs(logPID[0]); sendLogs(logPID[0]);
} case SERVER_INFO -> {
byte protocolVersion = CrabServer.RAC_VERSION;
String serverName = "CRAB";
byte[] nameBytes = serverName.getBytes(StandardCharsets.UTF_8);
byte[] response = new byte[1 + nameBytes.length];
response[0] = protocolVersion;
System.arraycopy(nameBytes, 0, response, 1, nameBytes.length);
respond(response);
} default -> System.out.println("PID not implemented: " + PID[0]); } default -> System.out.println("PID not implemented: " + PID[0]);
} }
socket.close(); socket.close();
@ -108,32 +99,28 @@ public class ServerThread implements Runnable {
} }
private byte[] readUntilChar(char c) throws IOException { private byte[] readUntilChar(char c) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); byte b[] = new byte[256];
int b; int i;
while ((b = input.read()) != -1) { for (i = 0;; i++) {
if (b == (byte) c) { b[i] = (byte)input.read();
if (b[i] == c)
break; break;
}
buffer.write(b);
} }
if (b == -1) { byte r[] = new byte[i];
throw new EOFException("Delimiter not found before EOF"); System.arraycopy(b, 0, r, 0, i);
} return r;
return buffer.toByteArray();
} }
private void sendLogs(byte PID) throws IOException { private void sendLogs(byte PID) throws IOException {
if (PID == LOGS) { if (PID == LOGS) {
respond(server.getCache().content()); respond(server.cache.content());
} else if (PID == CACHED_LOGS) { } else if (PID == CACHED_LOGS) {
String clientSize = Util.readAsciiNumber(in); String clientSize = Util.readAsciiNumber(in);
int clientSizeNum = Integer.parseInt(clientSize); int clientSizeNum = Integer.parseInt(clientSize);
byte[] serverLogs = server.getCache().content().getBytes(StandardCharsets.UTF_8); byte[] serverLogs = server.cache.content().getBytes(StandardCharsets.UTF_8);
int logPartSize = Math.max(0, serverLogs.length - clientSizeNum); int logPartSize = serverLogs.length - clientSizeNum;
byte[] logPart = new byte[logPartSize]; byte[] logPart = new byte[logPartSize];
if (logPartSize > 0) { System.arraycopy(serverLogs, serverLogs.length - logPartSize, logPart, 0, logPartSize);
System.arraycopy(serverLogs, clientSizeNum, logPart, 0, logPartSize);
}
respond(logPart); respond(logPart);
} }
} }