From a2f505c167df9807c80490922c9c4bcd088342a6 Mon Sep 17 00:00:00 2001 From: Louis Date: Fri, 20 Mar 2020 10:21:28 +0100 Subject: [PATCH] Add Register/Unregister --- doc/protocol.md | 3 +- src/protocolP2P/DiscoverRequest.java | 6 ++ src/protocolP2P/DiscoverResponse.java | 6 ++ src/protocolP2P/Payload.java | 8 +++ src/protocolP2P/ProtocolP2PPacketTCP.java | 12 ++++ src/protocolP2P/ProtocolP2PPacketUDP.java | 12 ++++ src/protocolP2P/Register.java | 77 +++++++++++++++++++++++ src/protocolP2P/Unregister.java | 77 +++++++++++++++++++++++ src/serverP2P/ServerManagementTCP.java | 51 +++++++++------ src/serverP2P/ServerManagementUDP.java | 51 +++++++++------ src/tracker/TrackerManagementTCP.java | 64 ++++++++++--------- src/tracker/TrackerManagementUDP.java | 65 ++++++++++--------- 12 files changed, 335 insertions(+), 97 deletions(-) create mode 100644 src/protocolP2P/Register.java create mode 100644 src/protocolP2P/Unregister.java diff --git a/doc/protocol.md b/doc/protocol.md index 352078f..64dae57 100644 --- a/doc/protocol.md +++ b/doc/protocol.md @@ -120,6 +120,7 @@ Payload contains: ``` 2 bytes: [] +? bytes: [] ``` #### Discover request @@ -128,7 +129,7 @@ If payload contains a filename, list all servers having this file in their list. ``` ? bytes: [] - +? bytes: [] ``` #### Discover response diff --git a/src/protocolP2P/DiscoverRequest.java b/src/protocolP2P/DiscoverRequest.java index b3a83aa..7ef1751 100644 --- a/src/protocolP2P/DiscoverRequest.java +++ b/src/protocolP2P/DiscoverRequest.java @@ -6,6 +6,12 @@ import localException.SizeError; import localException.ProtocolError; import localException.TransmissionError; +/** Representation of payload for discover request. + * @author Louis Royer + * @author Flavien Haas + * @author JS Auge + * @version 1.0 + */ public class DiscoverRequest extends Payload { private String filename; diff --git a/src/protocolP2P/DiscoverResponse.java b/src/protocolP2P/DiscoverResponse.java index b887dea..4c73e36 100644 --- a/src/protocolP2P/DiscoverResponse.java +++ b/src/protocolP2P/DiscoverResponse.java @@ -9,6 +9,12 @@ import localException.ProtocolError; import localException.TransmissionError; import tools.BytesArrayTools; +/** Representation of payload for discover response. + * @author Louis Royer + * @author Flavien Haas + * @author JS Auge + * @version 1.0 + */ public class DiscoverResponse extends Payload { private List hostList; diff --git a/src/protocolP2P/Payload.java b/src/protocolP2P/Payload.java index 8a84384..990df6b 100644 --- a/src/protocolP2P/Payload.java +++ b/src/protocolP2P/Payload.java @@ -7,6 +7,8 @@ import protocolP2P.HashRequest; import protocolP2P.HashResponse; import protocolP2P.DiscoverRequest; import protocolP2P.DiscoverResponse; +import protocolP2P.Register; +import protocolP2P.Unregister; import localException.ProtocolError; import localException.InternalError; import localException.TransmissionError; @@ -36,6 +38,8 @@ public class Payload { assert requestResponseCode != RequestResponseCode.HASH_RESPONSE || (this instanceof HashResponse) : "HASH_RESPONSE must use HashResponse class"; assert requestResponseCode != RequestResponseCode.DISCOVER_REQUEST || (this instanceof DiscoverRequest) : "DISCOVER_REQUEST must use DiscoverRequest class"; assert requestResponseCode != RequestResponseCode.DISCOVER_RESPONSE || (this instanceof DiscoverResponse) : "DISCOVER_RESPONSE must use DiscoverResponse class"; + assert requestResponseCode != RequestResponseCode.REGISTER || (this instanceof Register) : "REGISTER must use Register class"; + assert requestResponseCode != RequestResponseCode.UNREGISTER || (this instanceof Unregister) : "UNREGISTER must use Unregister class"; this.requestResponseCode = requestResponseCode; checkRequestResponseCode(); // this can throw InternalError } @@ -61,6 +65,8 @@ public class Payload { assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.HASH_RESPONSE || (this instanceof HashResponse) : "HASH_RESPONSE must use HashResponse class"; assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.DISCOVER_REQUEST || (this instanceof DiscoverRequest) : "DISCOVER_REQUEST must use DiscoverRequest class"; assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.DISCOVER_RESPONSE || (this instanceof DiscoverResponse) : "DISCOVER_RESPONSE must use DiscoverResponse class"; + assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.REGISTER || (this instanceof Register) : "REGISTER must use Register class"; + assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.UNREGISTER || (this instanceof Unregister) : "UNREGISTER must use Unregister class"; requestResponseCode = RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]); checkRequestResponseCode(); // this can throw InternalError } @@ -77,6 +83,8 @@ public class Payload { || (requestResponseCode == RequestResponseCode.HASH_RESPONSE && !(this instanceof HashResponse)) || (requestResponseCode == RequestResponseCode.DISCOVER_REQUEST && !(this instanceof DiscoverRequest)) || (requestResponseCode == RequestResponseCode.DISCOVER_RESPONSE && !(this instanceof DiscoverResponse)) + || (requestResponseCode == RequestResponseCode.REGISTER && !(this instanceof Register)) + || (requestResponseCode == RequestResponseCode.UNREGISTER && !(this instanceof Unregister)) ) { throw new InternalError(); } diff --git a/src/protocolP2P/ProtocolP2PPacketTCP.java b/src/protocolP2P/ProtocolP2PPacketTCP.java index ddde5f3..f2254f8 100644 --- a/src/protocolP2P/ProtocolP2PPacketTCP.java +++ b/src/protocolP2P/ProtocolP2PPacketTCP.java @@ -289,6 +289,18 @@ public class ProtocolP2PPacketTCP extends ProtocolP2PPacket { case HASH_RESPONSE: payload = (Payload) new HashResponse(packet); break; + case REGISTER: + payload = (Payload) new Register(packet); + break; + case UNREGISTER: + payload = (Payload) new Unregister(packet); + break; + case DISCOVER_REQUEST: + payload = (Payload) new DiscoverRequest(packet); + break; + case DISCOVER_RESPONSE: + payload = (Payload) new DiscoverResponse(packet); + break; default: payload = new Payload(packet); // this can throw TransmissionError break; diff --git a/src/protocolP2P/ProtocolP2PPacketUDP.java b/src/protocolP2P/ProtocolP2PPacketUDP.java index 500fa57..4bc98bb 100644 --- a/src/protocolP2P/ProtocolP2PPacketUDP.java +++ b/src/protocolP2P/ProtocolP2PPacketUDP.java @@ -287,6 +287,18 @@ public class ProtocolP2PPacketUDP extends ProtocolP2PPacket { case HASH_RESPONSE: payload = (Payload) new HashResponse(packet); break; + case REGISTER: + payload = (Payload) new Register(packet); + break; + case UNREGISTER: + payload = (Payload) new Unregister(packet); + break; + case DISCOVER_REQUEST: + payload = (Payload) new DiscoverRequest(packet); + break; + case DISCOVER_RESPONSE: + payload = (Payload) new DiscoverResponse(packet); + break; default: payload = new Payload(packet); // this can throw TransmissionError break; diff --git a/src/protocolP2P/Register.java b/src/protocolP2P/Register.java new file mode 100644 index 0000000..790ac2b --- /dev/null +++ b/src/protocolP2P/Register.java @@ -0,0 +1,77 @@ +package protocolP2P; +import protocolP2P.Payload; +import tools.HostItem; +import tools.BytesArrayTools; +import localException.SizeError; +import localException.InternalError; +import localException.TransmissionError; +import localException.ProtocolError; + +/** Representation of payload for unregister. + * @author Louis Royer + * @author Flavien Haas + * @author JS Auge + * @version 1.0 + */ +public class Register extends Payload { + private HostItem hostItem; + private static final int HOSTNAME_START_POSITION = PAYLOAD_START_POSITION + 2; + + /** Constructor with hostItem (typically used by client) + * @param hostItem Host you want to register. + * @throws InternalError + */ + public Register(HostItem hostItem) throws InternalError { + super(RequestResponseCode.REGISTER); + this.hostItem = hostItem; + } + + /** Constructor (typically used by server) with a byte[] parameter containing the Packet received. + * @param packet the full Packet received + * @throws SizeError + * @throws InternalError + * @throws ProtocolError + * @throws TransmissionError + */ + protected Register(byte[] packet) throws SizeError, ProtocolError, InternalError, TransmissionError { + super(packet); + int size = getPayloadSize(packet); + int port = BytesArrayTools.readInt16Bits(packet, PAYLOAD_START_POSITION); + String hostname = BytesArrayTools.readString(packet, HOSTNAME_START_POSITION, size - HOSTNAME_START_POSITION + PAYLOAD_START_POSITION); + hostItem = new HostItem(hostname, port); + } + + /** Returns a byte[] containing Packet with padding. + * This Packet is still incomplete and should not be send directly. + * ProtocolP2PPacket will use this method to generate the complete Packet. + * @return Packet with padding + * @throws InternalError + */ + protected byte[] toPacket() throws InternalError { + String hostname = hostItem.getHostname(); + // compute total size + int size = HOSTNAME_START_POSITION + hostname.length(); + byte[] packet = new byte[size + 1]; // java initialize all to zero + // set request/response code + packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; + // set Payload size + setPayloadSize(size - PAYLOAD_START_POSITION, packet); + // write port to Packet + try { + BytesArrayTools.write16Bits(packet, PAYLOAD_START_POSITION, hostItem.getPort()); + } catch (SizeError e) { + throw new InternalError(); + } + // write hostname to Packet + BytesArrayTools.write(packet, hostname, HOSTNAME_START_POSITION); + return packet; + } + + /** HostItem getter. + * @return hostItem + */ + public HostItem getHostItem() { + return hostItem; + } + +} diff --git a/src/protocolP2P/Unregister.java b/src/protocolP2P/Unregister.java new file mode 100644 index 0000000..8307a5b --- /dev/null +++ b/src/protocolP2P/Unregister.java @@ -0,0 +1,77 @@ +package protocolP2P; +import protocolP2P.Payload; +import tools.HostItem; +import tools.BytesArrayTools; +import localException.SizeError; +import localException.InternalError; +import localException.TransmissionError; +import localException.ProtocolError; + +/** Representation of payload for unregister. + * @author Louis Royer + * @author Flavien Haas + * @author JS Auge + * @version 1.0 + */ +public class Unregister extends Payload { + private HostItem hostItem; + private static final int HOSTNAME_START_POSITION = PAYLOAD_START_POSITION + 2; + + /** Constructor with hostItem (typically used by client) + * @param hostItem Host you want to register. + * @throws InternalError + */ + public Unregister(HostItem hostItem) throws InternalError { + super(RequestResponseCode.UNREGISTER); + this.hostItem = hostItem; + } + + /** Constructor (typically used by server) with a byte[] parameter containing the Packet received. + * @param packet the full Packet received + * @throws SizeError + * @throws InternalError + * @throws ProtocolError + * @throws TransmissionError + */ + protected Unregister(byte[] packet) throws SizeError, ProtocolError, InternalError, TransmissionError { + super(packet); + int size = getPayloadSize(packet); + int port = BytesArrayTools.readInt16Bits(packet, PAYLOAD_START_POSITION); + String hostname = BytesArrayTools.readString(packet, HOSTNAME_START_POSITION, size - HOSTNAME_START_POSITION + PAYLOAD_START_POSITION); + hostItem = new HostItem(hostname, port); + } + + /** Returns a byte[] containing Packet with padding. + * This Packet is still incomplete and should not be send directly. + * ProtocolP2PPacket will use this method to generate the complete Packet. + * @return Packet with padding + * @throws InternalError + */ + protected byte[] toPacket() throws InternalError { + String hostname = hostItem.getHostname(); + // compute total size + int size = HOSTNAME_START_POSITION + hostname.length(); + byte[] packet = new byte[size + 1]; // java initialize all to zero + // set request/response code + packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; + // set Payload size + setPayloadSize(size - PAYLOAD_START_POSITION, packet); + // write port to Packet + try { + BytesArrayTools.write16Bits(packet, PAYLOAD_START_POSITION, hostItem.getPort()); + } catch (SizeError e) { + throw new InternalError(); + } + // write hostname to Packet + BytesArrayTools.write(packet, hostname, HOSTNAME_START_POSITION); + return packet; + } + + /** HostItem getter. + * @return hostItem + */ + public HostItem getHostItem() { + return hostItem; + } + +} diff --git a/src/serverP2P/ServerManagementTCP.java b/src/serverP2P/ServerManagementTCP.java index 6001cdf..a136574 100644 --- a/src/serverP2P/ServerManagementTCP.java +++ b/src/serverP2P/ServerManagementTCP.java @@ -38,6 +38,8 @@ import java.util.Map; import protocolP2P.HashAlgorithm; import protocolP2P.HashRequest; import protocolP2P.HashResponse; +import protocolP2P.Register; +import protocolP2P.Unregister; /** Implementation of P2P-JAVA-PROJECT VERSION 1.0 protocol for TCP. @@ -82,12 +84,7 @@ public class ServerManagementTCP implements Runnable { */ public void run() { logger.writeTCP("Server sucessfully started", LogLevel.Info); - try { - registerTracker(); - } catch (Exception e) { - logger.writeTCP(e, LogLevel.Error); - System.exit(-4); - } + (new Thread(new TrackerRegisterer())).start(); do { try { Socket s = socket.accept(); @@ -341,20 +338,34 @@ public class ServerManagementTCP implements Runnable { } } - /** Register server on tracker - * @throws InternalError - * @throws IOException - * @throws SocketClosed - */ - public void registerTracker() throws InternalError, IOException, SocketClosed { - logger.writeTCP("Unregistering from tracker", LogLevel.Info); - ProtocolP2PPacket p = (ProtocolP2PPacket)new ProtocolP2PPacketTCP(new Payload(RequestResponseCode.UNREGISTER)); - p.sendRequest((Object)tracker.getTCPSocket()); - logger.writeTCP("Registering into tracker", LogLevel.Info); - p = (ProtocolP2PPacket)new ProtocolP2PPacketTCP(new Payload(RequestResponseCode.REGISTER)); - p.sendRequest((Object)tracker.getTCPSocket()); - logger.writeTCP("Registering completed", LogLevel.Debug); - tracker.closeTCPSocket(); + /** Private runnable class allowing to initialize tracker while initializing server. */ + private class TrackerRegisterer implements Runnable { + + /** Runnable implementation */ + public void run() { + try { + registerTracker(); + } catch (Exception e) { + logger.writeTCP(e, LogLevel.Error); + System.exit(-4); + } + } + /** Register server on tracker + * @throws InternalError + * @throws IOException + * @throws SocketClosed + */ + private void registerTracker() throws InternalError, IOException, SocketClosed { + HostItem host = new HostItem(InetAddress.getLocalHost().getCanonicalHostName(), TCPPort); + logger.writeTCP("Unregistering from tracker", LogLevel.Info); + ProtocolP2PPacket p = (ProtocolP2PPacket)new ProtocolP2PPacketTCP((Payload)new Unregister(host)); + p.sendRequest((Object)tracker.getTCPSocket()); + logger.writeTCP("Registering into tracker", LogLevel.Info); + p = (ProtocolP2PPacket)new ProtocolP2PPacketTCP((Payload)new Register(host)); + p.sendRequest((Object)tracker.getTCPSocket()); + logger.writeTCP("Registering completed", LogLevel.Debug); + tracker.closeTCPSocket(); + } } } diff --git a/src/serverP2P/ServerManagementUDP.java b/src/serverP2P/ServerManagementUDP.java index 0de0ef7..c082825 100644 --- a/src/serverP2P/ServerManagementUDP.java +++ b/src/serverP2P/ServerManagementUDP.java @@ -37,6 +37,8 @@ import protocolP2P.HashAlgorithm; import protocolP2P.HashRequest; import protocolP2P.HashResponse; import tools.HostItem; +import protocolP2P.Register; +import protocolP2P.Unregister; /** Implementation of P2P-JAVA-PROJECT VERSION 1.0 protocol for UDP. * @author Louis Royer @@ -77,12 +79,7 @@ public class ServerManagementUDP implements Runnable { */ public void run() { logger.writeUDP("Server sucessfully started", LogLevel.Info); - try { - registerTracker(); - } catch (Exception e) { - logger.writeUDP(e, LogLevel.Error); - System.exit(-4); - } + (new Thread(new TrackerRegisterer())).start(); while(true) { try { ProtocolP2PPacketUDP pd = new ProtocolP2PPacketUDP((Object)socket); @@ -278,19 +275,33 @@ public class ServerManagementUDP implements Runnable { } } - /** Register server on tracker - * @throws InternalError - * @throws IOException - * @throws SocketClosed - */ - public void registerTracker() throws InternalError, IOException, SocketClosed { - logger.writeUDP("Unregistering from tracker", LogLevel.Info); - ProtocolP2PPacket p = (ProtocolP2PPacket)new ProtocolP2PPacketUDP(new Payload(RequestResponseCode.UNREGISTER)); - p.sendRequest((Object)tracker.getUDPSocket()); - logger.writeUDP("Registering into tracker", LogLevel.Info); - p = (ProtocolP2PPacket)new ProtocolP2PPacketUDP(new Payload(RequestResponseCode.REGISTER)); - p.sendRequest((Object)tracker.getUDPSocket()); - tracker.closeUDPSocket(); - logger.writeUDP("Registering completed", LogLevel.Debug); +/** Private runnable class allowing to initialize tracker while initializing server. */ + private class TrackerRegisterer implements Runnable { + + /** Runnable implementation */ + public void run() { + try { + registerTracker(); + } catch (Exception e) { + logger.writeUDP(e, LogLevel.Error); + System.exit(-4); + } + } + /** Register server on tracker + * @throws InternalError + * @throws IOException + * @throws SocketClosed + */ + private void registerTracker() throws InternalError, IOException, SocketClosed { + HostItem host = new HostItem(InetAddress.getLocalHost().getCanonicalHostName(), UDPPort); + logger.writeUDP("Unregistering from tracker", LogLevel.Info); + ProtocolP2PPacket p = (ProtocolP2PPacket)new ProtocolP2PPacketUDP((Payload)new Unregister(host)); + p.sendRequest((Object)tracker.getUDPSocket()); + logger.writeUDP("Registering into tracker", LogLevel.Info); + p = (ProtocolP2PPacket)new ProtocolP2PPacketUDP((Payload)new Register(host)); + p.sendRequest((Object)tracker.getUDPSocket()); + logger.writeUDP("Registering completed", LogLevel.Debug); + tracker.closeUDPSocket(); + } } } diff --git a/src/tracker/TrackerManagementTCP.java b/src/tracker/TrackerManagementTCP.java index e8795d9..33f8ad2 100644 --- a/src/tracker/TrackerManagementTCP.java +++ b/src/tracker/TrackerManagementTCP.java @@ -8,6 +8,8 @@ import protocolP2P.ProtocolP2PPacketTCP; import protocolP2P.ProtocolP2PPacket; import protocolP2P.RequestResponseCode; import protocolP2P.Payload; +import protocolP2P.Register; +import protocolP2P.Unregister; import tools.HostItem; import java.util.ArrayList; import java.util.List; @@ -179,8 +181,13 @@ public class TrackerManagementTCP implements Runnable { * @throws InternalError */ private void handleRegister(ProtocolP2PPacketTCP pd) throws InternalError { + Payload p = pd.getPayload(); + assert p instanceof Register : "payload must be an instance of Register"; + if (!(p instanceof Register)) { + throw new InternalError(); + } // add host to known host list - HostItem host = pd.getHostItem(); + HostItem host = ((Register)p).getHostItem(); if (!hostList.contains(host)) { hostList.add(pd.getHostItem()); } @@ -188,8 +195,8 @@ public class TrackerManagementTCP implements Runnable { try { ProtocolP2PPacket pLReq = (ProtocolP2PPacket) new ProtocolP2PPacketTCP(new Payload(RequestResponseCode.LIST_REQUEST)); pLReq.sendRequest((Object)host.getTCPSocket()); - logger.writeTCP("Received REGISTER. Adding host " + host + " to list. Sending List request", LogLevel.Action); - handleListResponse((ProtocolP2PPacketTCP)pLReq.receiveResponse()); + logger.writeTCP("Received REGISTER from host " + pd.getHostItem() + ". Adding host " + host + " to list. Sending List request", LogLevel.Action); + handleListResponse((ProtocolP2PPacketTCP)pLReq.receiveResponse(), host); host.closeTCPSocket(); } catch (Exception e) { // remove from list because list request could not be send @@ -204,8 +211,14 @@ public class TrackerManagementTCP implements Runnable { * @throws InternalError */ private void handleUnregister(ProtocolP2PPacketTCP pd) throws InternalError { - HostItem host = pd.getHostItem(); - logger.writeTCP("Received UNREGISTER. Removing host " + host, LogLevel.Action); + Payload p = pd.getPayload(); + assert p instanceof Unregister : "payload must be an instance of Unregister"; + if (!(p instanceof Unregister)) { + sendInternalError(pd); + throw new InternalError(); + } + HostItem host = ((Unregister)p).getHostItem(); + logger.writeTCP("Received UNREGISTER from host " + pd.getHostItem() + ". Removing host " + host, LogLevel.Action); hostList.remove(host); for(String f: fileList.keySet()) { fileList.get(f).remove(host); @@ -239,30 +252,25 @@ public class TrackerManagementTCP implements Runnable { * @param pd ProtocolP2PPacketTCP response * @throws InternalError */ - private void handleListResponse(ProtocolP2PPacketTCP pd) throws InternalError { - HostItem host = pd.getHostItem(); - if (!hostList.contains(host)) { - logger.writeTCP("Received LIST RESPONSE from host " + host + " but it is not registered.", LogLevel.Action); + private void handleListResponse(ProtocolP2PPacketTCP pd, HostItem host) throws InternalError { + logger.writeTCP("Received LIST RESPONSE from host " + host + ": registered host.", LogLevel.Action); + Payload p = pd.getPayload(); + assert p instanceof FileList: "payload must be an instance of FileList"; + if (!(p instanceof FileList)) { + throw new InternalError(); } else { - logger.writeTCP("Received LIST RESPONSE from host " + host + ": registered host.", LogLevel.Action); - Payload p = pd.getPayload(); - assert p instanceof FileList: "payload must be an instance of FileList"; - if (!(p instanceof FileList)) { - sendInternalError(pd); - } else { - String[] f = ((FileList)p).getFileList(); - for (String file: f) { - List h = fileList.get(file); - if (h != null) { - if (!h.contains(host)) { - h.add(host); - } - } else { - List emptyH = new ArrayList<>(); - emptyH.add(host); - fileList.put(file, emptyH); - } - } + String[] f = ((FileList)p).getFileList(); + for (String file: f) { + List h = fileList.get(file); + if (h != null) { + if (!h.contains(host)) { + h.add(host); + } + } else { + List emptyH = new ArrayList<>(); + emptyH.add(host); + fileList.put(file, emptyH); + } } } } diff --git a/src/tracker/TrackerManagementUDP.java b/src/tracker/TrackerManagementUDP.java index c11c54c..3a93fe6 100644 --- a/src/tracker/TrackerManagementUDP.java +++ b/src/tracker/TrackerManagementUDP.java @@ -6,6 +6,8 @@ import protocolP2P.ProtocolP2PPacketUDP; import protocolP2P.ProtocolP2PPacket; import protocolP2P.RequestResponseCode; import protocolP2P.Payload; +import protocolP2P.Register; +import protocolP2P.Unregister; import tools.HostItem; import java.util.ArrayList; import java.util.List; @@ -131,8 +133,14 @@ public class TrackerManagementUDP implements Runnable { * @throws InternalError */ private void handleRegister(ProtocolP2PPacketUDP pd) throws InternalError { + Payload p = pd.getPayload(); + assert p instanceof Register : "payload must be an instance of Register"; + if (!(p instanceof Register)) { + sendInternalError(pd); + throw new InternalError(); + } // add host to known host list - HostItem host = pd.getHostItem(); + HostItem host = ((Register)p).getHostItem(); if (!hostList.contains(host)) { hostList.add(pd.getHostItem()); } @@ -140,8 +148,8 @@ public class TrackerManagementUDP implements Runnable { try { ProtocolP2PPacket pLReq =(ProtocolP2PPacket)new ProtocolP2PPacketUDP(new Payload(RequestResponseCode.LIST_REQUEST)); pLReq.sendRequest((Object)host.getUDPSocket()); - logger.writeUDP("Received REGISTER. Adding host " + host + " to list. Sending List request", LogLevel.Action); - handleListResponse((ProtocolP2PPacketUDP)pLReq.receiveResponse()); + logger.writeUDP("Received REGISTER from host " + pd.getHostItem() + ". Adding host " + host + " to list. Sending List request", LogLevel.Action); + handleListResponse((ProtocolP2PPacketUDP)pLReq.receiveResponse(), host); host.closeUDPSocket(); } catch (Exception e) { // remove from list because list request could not be send @@ -156,8 +164,14 @@ public class TrackerManagementUDP implements Runnable { * @throws InternalError */ private void handleUnregister(ProtocolP2PPacketUDP pd) throws InternalError { - HostItem host = pd.getHostItem(); - logger.writeUDP("Received UNREGISTER. Removing host " + host, LogLevel.Action); + Payload p = pd.getPayload(); + assert p instanceof Unregister : "payload must be an instance of Unregister"; + if (!(p instanceof Unregister)) { + sendInternalError(pd); + throw new InternalError(); + } + HostItem host = ((Unregister)p).getHostItem(); + logger.writeUDP("Received UNREGISTER from host " + pd.getHostItem() + ". Removing host " + host, LogLevel.Action); hostList.remove(host); for(String f: fileList.keySet()) { fileList.get(f).remove(host); @@ -191,30 +205,25 @@ public class TrackerManagementUDP implements Runnable { * @param pd ProtocolP2PPacketUDP response * @throws InternalError */ - private void handleListResponse(ProtocolP2PPacketUDP pd) throws InternalError { - HostItem host = pd.getHostItem(); - if (!hostList.contains(host)) { - logger.writeUDP("Received LIST RESPONSE from host " + host + " but it is not registered.", LogLevel.Action); + private void handleListResponse(ProtocolP2PPacketUDP pd, HostItem host) throws InternalError { + logger.writeUDP("Received LIST RESPONSE from host " + host, LogLevel.Action); + Payload p = pd.getPayload(); + assert p instanceof FileList: "payload must be an instance of FileList"; + if (!(p instanceof FileList)) { + throw new InternalError(); } else { - logger.writeUDP("Received LIST RESPONSE from host " + host + ": registered host.", LogLevel.Action); - Payload p = pd.getPayload(); - assert p instanceof FileList: "payload must be an instance of FileList"; - if (!(p instanceof FileList)) { - sendInternalError(pd); - } else { - String[] f = ((FileList)p).getFileList(); - for (String file: f) { - List h = fileList.get(file); - if (h != null) { - if (!h.contains(host)) { - h.add(host); - } - } else { - List emptyH = new ArrayList<>(); - emptyH.add(host); - fileList.put(file, emptyH); - } - } + String[] f = ((FileList)p).getFileList(); + for (String file: f) { + List h = fileList.get(file); + if (h != null) { + if (!h.contains(host)) { + h.add(host); + } + } else { + List emptyH = new ArrayList<>(); + emptyH.add(host); + fileList.put(file, emptyH); + } } } }