|
|
|
@ -6,6 +6,8 @@ import java.net.InetAddress;
|
|
|
|
|
import java.net.SocketException;
|
|
|
|
|
import java.nio.file.Paths;
|
|
|
|
|
import java.nio.file.Files;
|
|
|
|
|
import java.security.MessageDigest;
|
|
|
|
|
import java.security.NoSuchAlgorithmException;
|
|
|
|
|
import java.net.ServerSocket;
|
|
|
|
|
import java.net.Socket;
|
|
|
|
|
import protocolP2P.ProtocolP2PPacketTCP;
|
|
|
|
@ -30,6 +32,11 @@ import remoteException.EmptyFile;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import tools.Logger;
|
|
|
|
|
import tools.LogLevel;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import protocolP2P.HashAlgorithm;
|
|
|
|
|
import protocolP2P.HashRequest;
|
|
|
|
|
import protocolP2P.HashResponse;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Implementation of P2P-JAVA-PROJECT VERSION 1.0 protocol for TCP.
|
|
|
|
@ -41,6 +48,7 @@ import tools.LogLevel;
|
|
|
|
|
public class ServerManagementTCP implements Runnable {
|
|
|
|
|
|
|
|
|
|
private String[] fileList;
|
|
|
|
|
private Map<String, byte[]> sha512 = new HashMap<>();
|
|
|
|
|
private String baseDirectory;
|
|
|
|
|
private int TCPPort;
|
|
|
|
|
private ServerSocket socket;
|
|
|
|
@ -55,6 +63,7 @@ public class ServerManagementTCP implements Runnable {
|
|
|
|
|
this.baseDirectory = baseDirectory;
|
|
|
|
|
this.TCPPort = TCPPort;
|
|
|
|
|
initFileList();
|
|
|
|
|
initSha512();
|
|
|
|
|
try {
|
|
|
|
|
socket = new ServerSocket(TCPPort);
|
|
|
|
|
} catch (SocketException e) {
|
|
|
|
@ -123,6 +132,10 @@ public class ServerManagementTCP implements Runnable {
|
|
|
|
|
logger.writeTCP(addr + "LIST_REQUEST", LogLevel.Action);
|
|
|
|
|
sendListResponse(pd);
|
|
|
|
|
break;
|
|
|
|
|
case HASH_REQUEST:
|
|
|
|
|
logger.writeTCP(addr + "HASH_REQUEST", LogLevel.Action);
|
|
|
|
|
sendHashResponse(pd);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
logger.writeTCP(addr + "Received grabbage", LogLevel.Action);
|
|
|
|
|
sendInternalError(pd);
|
|
|
|
@ -158,6 +171,22 @@ public class ServerManagementTCP implements Runnable {
|
|
|
|
|
Arrays.sort(fileList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Init sha512 map.
|
|
|
|
|
*/
|
|
|
|
|
private void initSha512() {
|
|
|
|
|
for(String f: fileList) {
|
|
|
|
|
try {
|
|
|
|
|
MessageDigest md = MessageDigest.getInstance(HashAlgorithm.SHA512.getName());
|
|
|
|
|
sha512.put(f, md.digest(Files.readAllBytes(Paths.get(baseDirectory + f))));
|
|
|
|
|
md.reset();
|
|
|
|
|
} catch (NoSuchAlgorithmException e) {
|
|
|
|
|
logger.writeTCP("sha512 not supported", LogLevel.Error);
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
logger.writeTCP("cannot read " + f, LogLevel.Warning);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Send an internal error message.
|
|
|
|
|
* @param pd ProtocolP2PPacketTCP to respond
|
|
|
|
|
*/
|
|
|
|
@ -187,6 +216,46 @@ public class ServerManagementTCP implements Runnable {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Send hash response to hash request
|
|
|
|
|
* @param pd Request received
|
|
|
|
|
*/
|
|
|
|
|
private void sendHashResponse(ProtocolP2PPacketTCP pd) {
|
|
|
|
|
Payload p = pd.getPayload();
|
|
|
|
|
assert p instanceof HashRequest : "payload must be an instance of HashRequest";
|
|
|
|
|
if (!(p instanceof HashRequest)) {
|
|
|
|
|
sendInternalError(pd);
|
|
|
|
|
} else {
|
|
|
|
|
String filename = ((HashRequest)p).getFilename();
|
|
|
|
|
if (Arrays.binarySearch(fileList, filename) >= 0) {
|
|
|
|
|
Map<HashAlgorithm, byte[]> hashes = new HashMap<>();
|
|
|
|
|
for (HashAlgorithm h : ((HashRequest)p).getAlgoList()) {
|
|
|
|
|
switch (h) {
|
|
|
|
|
case SHA512:
|
|
|
|
|
hashes.put(h, sha512.get(filename));
|
|
|
|
|
break;
|
|
|
|
|
case MD5:
|
|
|
|
|
default:
|
|
|
|
|
hashes.put(h, new byte[0]);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
pd.sendResponse((ProtocolP2PPacket)new ProtocolP2PPacketTCP((Payload)(new HashResponse(filename, hashes))));
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
logger.writeTCP(e, LogLevel.Error);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// file not found
|
|
|
|
|
try {
|
|
|
|
|
pd.sendResponse((ProtocolP2PPacket)new ProtocolP2PPacketTCP(new Payload(RequestResponseCode.NOT_FOUND)));
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
logger.writeTCP(e, LogLevel.Error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Send response to load request
|
|
|
|
|
* @param pd Request received
|
|
|
|
|
*/
|
|
|
|
|