From 77655cb828b85ce034375d268d8449e0c625c3b2 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Fri, 27 Mar 2020 18:00:06 +0100 Subject: [PATCH] Add DENIED protocol element --- doc/protocol.md | 5 +- src/protocolP2P/Denied.java | 86 +++++++++++++++++++++++ src/protocolP2P/Payload.java | 4 ++ src/protocolP2P/ProtocolP2PPacketTCP.java | 5 ++ src/protocolP2P/ProtocolP2PPacketUDP.java | 5 ++ src/protocolP2P/RequestResponseCode.java | 4 +- src/remoteException/UnknownHost.java | 7 ++ 7 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 src/protocolP2P/Denied.java create mode 100644 src/remoteException/UnknownHost.java diff --git a/doc/protocol.md b/doc/protocol.md index 045382c..c5e5460 100644 --- a/doc/protocol.md +++ b/doc/protocol.md @@ -29,6 +29,7 @@ x bytes: [(bytes 8-?): PAYLOAD] - `HASH` (0x82) - `DISCOVER` (0x83) - `RATIO` (0x86) + - `DENIED` (0x87) - `VERSION ERROR` (0xC0) - `PROTOCOL ERROR` (0xC1) - `INTERNAL ERROR` (0xC2) @@ -37,7 +38,6 @@ x bytes: [(bytes 8-?): PAYLOAD] - `EMPTY FILE` (0xC5) - `NOT A TRACKER` (0xC6) - `UNKNOWN HOST` (0xC7) - - `DENIED` (0xC8) ### List Payload size for list request is always zero. @@ -197,7 +197,8 @@ Payload size is zero. #### Denied Contains ```text -?bytes: filename +8 bytes: offset of content asked +? bytes: filename ``` ### Other response code (errors) diff --git a/src/protocolP2P/Denied.java b/src/protocolP2P/Denied.java new file mode 100644 index 0000000..7b20eec --- /dev/null +++ b/src/protocolP2P/Denied.java @@ -0,0 +1,86 @@ +package protocolP2P; +import protocolP2P.Payload; +import protocolP2P.RequestResponseCode; +import localException.ProtocolError; +import localException.InternalError; +import localException.SizeError; +import localException.TransmissionError; +import tools.BytesArrayTools; + +/** Representation of payload for denied response. + * @author Louis Royer + * @author Flavien Haas + * @author JS Auge + * @version 1.0 + */ +public class Denied extends Payload { + private String filename; + private long offset; + static final private int OFFSET_POSITION = PAYLOAD_START_POSITION; + static final private int FILENAME_POSITION = OFFSET_POSITION + 8; + + /** Constructor (typically used by server) with informations about file part to send as parameters. + * @param filename name of the file to send + * @param offset where in the file begins the part we are sending + * @throws InternalError + */ + public Denied(String filename, long offset) throws InternalError { + super(RequestResponseCode.DENIED); + /* asserts to help debugging */ + assert offset >= 0 : "offset cannot be negative"; + assert filename != null : "filename is required"; + if (offset < 0 || filename == null) { + throw new InternalError(); + } + this.filename = filename; + this.offset = offset; + } + + /** Constructor (typically used by client) with Packet received as parameter. + * @param packet the full Packet received + * @throws SizeError + * @throws InternalError + * @throws TransmissionError + */ + protected Denied(byte[] packet) throws TransmissionError, SizeError, ProtocolError, InternalError { + super(packet); + int filenameSize = getPayloadSize(packet) - FILENAME_POSITION + PAYLOAD_START_POSITION; + offset = BytesArrayTools.readLong(packet, OFFSET_POSITION); + filename = BytesArrayTools.readString(packet, FILENAME_POSITION, filenameSize); + } + + /** 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 { + // compute total size + int size = FILENAME_POSITION + filename.length(); + byte[] packet = new byte[size]; // 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 offset to Packet + BytesArrayTools.write(packet, OFFSET_POSITION, offset); + // write filename to Packet + BytesArrayTools.write(packet, filename, FILENAME_POSITION); + return packet; + } + + /** filename getter. + * @return String + */ + public String getFilename() { + return filename; + } + + /** offset getter. + * @return offset + */ + public long getOffset() { + return offset; + } +} diff --git a/src/protocolP2P/Payload.java b/src/protocolP2P/Payload.java index 5f2a3a2..e41f94c 100644 --- a/src/protocolP2P/Payload.java +++ b/src/protocolP2P/Payload.java @@ -12,6 +12,7 @@ import protocolP2P.Unregister; import protocolP2P.RatioRequest; import protocolP2P.RatioResponse; import protocolP2P.UpdateRatio; +import protocolP2P.Denied; import localException.ProtocolError; import localException.InternalError; import localException.TransmissionError; @@ -46,6 +47,7 @@ public class Payload { assert requestResponseCode != RequestResponseCode.RATIO_REQUEST || (this instanceof RatioRequest) : "RATIO_REQUEST must use RatioRequest class"; assert requestResponseCode != RequestResponseCode.RATIO_RESPONSE || (this instanceof RatioResponse) : "RATIO_RESPONSE must use RatioResponse class"; assert requestResponseCode != RequestResponseCode.UPDATE_RATIO || (this instanceof UpdateRatio) : "UPDATE_RATIO must use UpdateRatio class"; + assert requestResponseCode != RequestResponseCode.DENIED || (this instanceof Denied) : "DENIED must use Denied class"; this.requestResponseCode = requestResponseCode; checkRequestResponseCode(); // this can throw InternalError } @@ -76,6 +78,7 @@ public class Payload { assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.RATIO_REQUEST || (this instanceof RatioRequest) : "RATIO_REQUEST must use RatioRequest class"; assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.RATIO_RESPONSE || (this instanceof RatioResponse) : "RATIO_RESPONSE must use RatioResponse class"; assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.UPDATE_RATIO || (this instanceof UpdateRatio) : "UPDATE_RATIO must use UpdateRatio class"; + assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.DENIED || (this instanceof Denied) : "DENIED must use Denied class"; requestResponseCode = RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]); checkRequestResponseCode(); // this can throw InternalError } @@ -97,6 +100,7 @@ public class Payload { || (requestResponseCode == RequestResponseCode.RATIO_REQUEST && !(this instanceof RatioRequest)) || (requestResponseCode == RequestResponseCode.RATIO_RESPONSE && !(this instanceof RatioResponse)) || (requestResponseCode == RequestResponseCode.UPDATE_RATIO && !(this instanceof UpdateRatio)) + || (requestResponseCode == RequestResponseCode.DENIED && !(this instanceof Denied)) ) { throw new InternalError(); } diff --git a/src/protocolP2P/ProtocolP2PPacketTCP.java b/src/protocolP2P/ProtocolP2PPacketTCP.java index 4eb2bfd..0c348e5 100644 --- a/src/protocolP2P/ProtocolP2PPacketTCP.java +++ b/src/protocolP2P/ProtocolP2PPacketTCP.java @@ -21,6 +21,7 @@ import protocolP2P.FilePart; import protocolP2P.RatioRequest; import protocolP2P.RatioResponse; import protocolP2P.UpdateRatio; +import protocolP2P.Denied; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; @@ -145,6 +146,7 @@ public class ProtocolP2PPacketTCP < T extends Payload > extends ProtocolP2PPacke case DISCOVER_RESPONSE: case NOT_A_TRACKER: case RATIO_RESPONSE: + case DENIED: // we were expecting a request, but we are receiving a response throw new ProtocolError(); default : @@ -332,6 +334,9 @@ public class ProtocolP2PPacketTCP < T extends Payload > extends ProtocolP2PPacke case UPDATE_RATIO: payload = (Payload) new UpdateRatio(packet); break; + case DENIED: + payload = (Payload) new Denied(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 e7fbbc5..894be60 100644 --- a/src/protocolP2P/ProtocolP2PPacketUDP.java +++ b/src/protocolP2P/ProtocolP2PPacketUDP.java @@ -22,6 +22,7 @@ import protocolP2P.FilePart; import protocolP2P.RatioRequest; import protocolP2P.RatioResponse; import protocolP2P.UpdateRatio; +import protocolP2P.Denied; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketAddress; @@ -138,6 +139,7 @@ public class ProtocolP2PPacketUDP < T extends Payload> extends ProtocolP2PPacket case DISCOVER_RESPONSE: case NOT_A_TRACKER: case RATIO_RESPONSE: + case DENIED: // we were expecting a request, but we are receiving a response throw new ProtocolError(); default : @@ -317,6 +319,9 @@ public class ProtocolP2PPacketUDP < T extends Payload> extends ProtocolP2PPacket case UPDATE_RATIO: payload = (Payload) new UpdateRatio(packet); break; + case DENIED: + payload = (Payload) new Denied(packet); + break; default: payload = new Payload(packet); // this can throw TransmissionError break; diff --git a/src/protocolP2P/RequestResponseCode.java b/src/protocolP2P/RequestResponseCode.java index b2994f4..1941870 100644 --- a/src/protocolP2P/RequestResponseCode.java +++ b/src/protocolP2P/RequestResponseCode.java @@ -25,6 +25,7 @@ public enum RequestResponseCode { HASH_RESPONSE(CodeType.RESPONSE, (byte)0x82), DISCOVER_RESPONSE(CodeType.RESPONSE, (byte)0x83), RATIO_RESPONSE(CodeType.RESPONSE, (byte)0x86), + DENIED(CodeType.RESPONSE, (byte)0x87), VERSION_ERROR(CodeType.ERROR, (byte)0xC0), PROTOCOL_ERROR(CodeType.ERROR, (byte)0xC1), INTERNAL_ERROR(CodeType.ERROR, (byte)0xC2), @@ -32,8 +33,7 @@ public enum RequestResponseCode { NOT_FOUND(CodeType.ERROR, (byte)0xC4), EMPTY_FILE(CodeType.ERROR, (byte)0xC5), NOT_A_TRACKER(CodeType.ERROR, (byte)0xC6), - UNKNOWN_HOST(CodeType.ERROR, (byte)0xC7), - DENIED(CodeType.ERROR, (byte)0xC8); + UNKNOWN_HOST(CodeType.ERROR, (byte)0xC7); public final CodeType codeType; public final byte codeValue; diff --git a/src/remoteException/UnknownHost.java b/src/remoteException/UnknownHost.java new file mode 100644 index 0000000..0c2ccad --- /dev/null +++ b/src/remoteException/UnknownHost.java @@ -0,0 +1,7 @@ +package remoteException; + +import exception.RemoteException; + +public class UnknownHost extends RemoteException { + private static final long serialVersionUID = 12L; +}