Finish implementing fragment verification.
This commit is contained in:
parent
96c9864092
commit
fcd985b570
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -25,6 +25,7 @@ public final class FragmentReceiver {
|
||||
private PacketLoader packetLoader;
|
||||
private IPacketFactory packetFactory;
|
||||
private boolean verifyResponses = false;
|
||||
private boolean makeSureSendDataVerified = false;
|
||||
|
||||
/**
|
||||
* Constructs a new FragmentReceiver with the specified {@link PacketLoader} and {@link IPacketFactory}.
|
||||
@ -262,12 +263,36 @@ public final class FragmentReceiver {
|
||||
|
||||
/**
|
||||
* Sets whether responses should be verified.
|
||||
* If set to false, {@link #setSentDataWillBeAllVerified(boolean)} will be set to false too.
|
||||
*
|
||||
* @param state If responses should be verified.
|
||||
*/
|
||||
public void setResponseVerification(boolean state) {
|
||||
synchronized (slock) {
|
||||
verifyResponses = state;
|
||||
if (makeSureSendDataVerified && !state) makeSureSendDataVerified = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether all sent fragments are verified to be equal.
|
||||
*
|
||||
* @return If all sent fragments will be verified to be equal.
|
||||
*/
|
||||
public boolean shouldSentDataBeAllVerified() {
|
||||
return makeSureSendDataVerified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether all sent fragments are verified to be equal.
|
||||
* Requires {@link #setResponseVerification(boolean)} set to true.
|
||||
*
|
||||
* @param state If all sent fragments will be verified to be equal.
|
||||
*/
|
||||
public void setSentDataWillBeAllVerified(boolean state) {
|
||||
synchronized (slock) {
|
||||
if (!verifyResponses) return;
|
||||
makeSureSendDataVerified = state;
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,6 +301,7 @@ public final class FragmentReceiver {
|
||||
* the {@link FragmentSendCompletePacket} or {@link FragmentRetrySendPacket} packets are sent.
|
||||
* A {@link FragmentSendCompletePacket} is sent if completely received and a
|
||||
* {@link FragmentRetrySendPacket} is sent if not completely received.
|
||||
* This excludes empty packets due to {@link #shouldSentDataBeAllVerified()}.
|
||||
*
|
||||
* @return The number of send packet calls before a completion or restart is forced.
|
||||
*/
|
||||
@ -288,6 +314,7 @@ public final class FragmentReceiver {
|
||||
* the {@link FragmentSendCompletePacket} or {@link FragmentRetrySendPacket} packets are sent.
|
||||
* A {@link FragmentSendCompletePacket} is sent if completely received and a
|
||||
* {@link FragmentRetrySendPacket} is sent if not completely received.
|
||||
* This excludes empty packets due to {@link #shouldSentDataBeAllVerified()}.
|
||||
*
|
||||
* @param numberOfEmptySends The number of empty sends to allow.
|
||||
* @throws IllegalArgumentException numberOfEmptySends is less than 1.
|
||||
@ -297,6 +324,28 @@ public final class FragmentReceiver {
|
||||
numberOfEmptySendsTillForced = numberOfEmptySends;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops data verification for the specified Packet ID when {@link #shouldSentDataBeAllVerified()} is true.
|
||||
*
|
||||
* @param id The PacketID to act on.
|
||||
*/
|
||||
public void stopDataVerificationAndCompleteReceive(int id) {
|
||||
synchronized (slock) {
|
||||
if (!makeSureSendDataVerified) return;
|
||||
FragmentInput input = registry.get(id);
|
||||
if (input != null) input.verifyReceived = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops data verification for all packets being received when {@link #shouldSentDataBeAllVerified()} is true.
|
||||
*/
|
||||
public void stopAllDataVerificationAndCompleteReceive() {
|
||||
synchronized (slock) {
|
||||
for (int c : registry.keySet()) registry.get(c).verifyReceived = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class provides the ability to store allocated responses to be sent back.
|
||||
*
|
||||
@ -334,6 +383,7 @@ public final class FragmentReceiver {
|
||||
private int sendsTillCompleteForced;
|
||||
private boolean fsendActive = false;
|
||||
private final FragmentMessagePacket[] messagePackets;
|
||||
public boolean verifyReceived = false;
|
||||
|
||||
public FragmentInput(int id, int count, UUID aid) {
|
||||
packetID = id;
|
||||
@ -355,12 +405,16 @@ public final class FragmentReceiver {
|
||||
if (fsendActive) {
|
||||
if (sendsTillCompleteForced > 0) sendsTillCompleteForced--;
|
||||
} else fsendActive = true;
|
||||
if (sendsTillCompleteForced == 0) return (idsToReceive.size() < 1) ? new FragmentSendCompletePacket(packetID, true) : new FragmentRetrySendPacket(packetID, false);
|
||||
if (sendsTillCompleteForced == 0 && !(makeSureSendDataVerified && !verifyReceived)) return (idsToReceive.size() < 1) ? new FragmentSendCompletePacket(packetID, true) : new FragmentRetrySendPacket(packetID, false);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void receivePacket(IPacket packetIn) {
|
||||
if ((packetIn instanceof FragmentSendCompletePacket && !((FragmentSendCompletePacket) packetIn).isAcknowledgement())) sendsTillCompleteForced = 0;
|
||||
if (packetIn instanceof FragmentSendVerifyCompletePacket) {
|
||||
sendsTillCompleteForced = 0;
|
||||
verifyReceived = true;
|
||||
}
|
||||
if ((packetIn instanceof FragmentRetrySendPacket && ((FragmentRetrySendPacket) packetIn).isAcknowledgement())) sendsTillCompleteForced = numberOfEmptySendsTillForced + 1;
|
||||
if (packetIn instanceof FragmentMessagePacket) {
|
||||
FragmentMessagePacket messagePacket = (FragmentMessagePacket) packetIn;
|
||||
@ -371,7 +425,7 @@ public final class FragmentReceiver {
|
||||
}
|
||||
|
||||
public IPacket consume() throws PacketException {
|
||||
if (consumeDone || idsToReceive.size() > 0 || messagePackets.length < 1) return null;
|
||||
if (consumeDone || idsToReceive.size() > 0 || messagePackets.length < 1 || (makeSureSendDataVerified && !verifyReceived)) return null;
|
||||
ByteArrayOutputStream packetStream = new ByteArrayOutputStream(messagePackets[0].getFragmentMessage().length);
|
||||
for (FragmentMessagePacket messagePacket : messagePackets) {
|
||||
try {
|
||||
|
@ -19,6 +19,7 @@ public final class FragmentSender {
|
||||
private int splitSize = 496;
|
||||
private PacketLoader packetLoader;
|
||||
private boolean verifyResponses = false;
|
||||
private boolean makeSureSendDataVerified = false;
|
||||
|
||||
/**
|
||||
* Constructs a new FragmentSender with the specified {@link PacketLoader}.
|
||||
@ -241,12 +242,58 @@ public final class FragmentSender {
|
||||
|
||||
/**
|
||||
* Sets whether responses should be verified.
|
||||
* If set to false, {@link #setSentDataWillBeAllVerified(boolean)} will be set to false too.
|
||||
*
|
||||
* @param state If responses should be verified.
|
||||
*/
|
||||
public void setResponseVerification(boolean state) {
|
||||
synchronized (slock) {
|
||||
verifyResponses = state;
|
||||
if (makeSureSendDataVerified && !state) makeSureSendDataVerified = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether all sent fragments are verified to be equal.
|
||||
*
|
||||
* @return If all sent fragments will be verified to be equal.
|
||||
*/
|
||||
public boolean shouldSentDataBeAllVerified() {
|
||||
return makeSureSendDataVerified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether all sent fragments are verified to be equal.
|
||||
* Requires {@link #setResponseVerification(boolean)} set to true.
|
||||
*
|
||||
* @param state If all sent fragments will be verified to be equal.
|
||||
*/
|
||||
public void setSentDataWillBeAllVerified(boolean state) {
|
||||
synchronized (slock) {
|
||||
if (!verifyResponses) return;
|
||||
makeSureSendDataVerified = state;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops data verification for the specified Packet ID when {@link #shouldSentDataBeAllVerified()} is true.
|
||||
*
|
||||
* @param id The PacketID to act on.
|
||||
*/
|
||||
public void stopDataVerificationAndCompleteSend(int id) {
|
||||
synchronized (slock) {
|
||||
if (!makeSureSendDataVerified) return;
|
||||
FragmentOutput output = registry.get(id);
|
||||
if (output != null) output.forceDataVerifiedSendStop = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops data verification for all packets being sent when {@link #shouldSentDataBeAllVerified()} is true.
|
||||
*/
|
||||
public void stopAllDataVerificationAndCompleteSend() {
|
||||
synchronized (slock) {
|
||||
for (int c : registry.keySet()) registry.get(c).forceDataVerifiedSendStop = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,6 +310,7 @@ public final class FragmentSender {
|
||||
private final ArrayList<Integer> msgToResendCurrent = new ArrayList<>();
|
||||
private int msgPacketIndex = 0;
|
||||
public boolean isResending = false;
|
||||
public boolean forceDataVerifiedSendStop = false;
|
||||
|
||||
public FragmentOutput(int id, byte[] toSplit) {
|
||||
packetID = id;
|
||||
@ -282,12 +330,14 @@ public final class FragmentSender {
|
||||
msgPacketIndex = 0;
|
||||
return new FragmentRetrySendPacket(packetID, true);
|
||||
}
|
||||
if (!isResending && makeSureSendDataVerified && msgPacketIndex >= messagePackets.length && !forceDataVerifiedSendStop) setResendingOn(true);
|
||||
if (isResending) {
|
||||
if (makeSureSendDataVerified && msgPacketIndex >= msgToResendCurrent.size() && !forceDataVerifiedSendStop) setResendingOn(true);
|
||||
if (msgPacketIndex < msgToResendCurrent.size()) return messagePackets[msgToResendCurrent.get(msgPacketIndex++)];
|
||||
} else {
|
||||
if (msgPacketIndex < messagePackets.length) return messagePackets[msgPacketIndex++];
|
||||
}
|
||||
return new FragmentSendCompletePacket(packetID, false);
|
||||
return (makeSureSendDataVerified && (msgToResend.size() < 1 || forceDataVerifiedSendStop)) ? new FragmentSendVerifyCompletePacket(packetID) : new FragmentSendCompletePacket(packetID, false);
|
||||
}
|
||||
|
||||
public boolean shouldBeRemovedReceivePacket(IPacket packetIn) {
|
||||
@ -300,15 +350,17 @@ public final class FragmentSender {
|
||||
if (!verifyResponses || compareData(responsePacket.getFragmentMessage(), messagePackets[responsePacket.getFragmentID()].getFragmentMessage()))
|
||||
msgToResend.remove(responsePacket.getFragmentID());
|
||||
}
|
||||
if (packetIn instanceof FragmentRetrySendPacket && !((FragmentRetrySendPacket) packetIn).isAcknowledgement()) {
|
||||
msgPacketIndex = -1;
|
||||
isResending = true;
|
||||
msgToResendCurrent.clear();
|
||||
msgToResendCurrent.addAll(msgToResend);
|
||||
}
|
||||
if (packetIn instanceof FragmentRetrySendPacket && !((FragmentRetrySendPacket) packetIn).isAcknowledgement()) setResendingOn(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setResendingOn(boolean zeroIndex) {
|
||||
msgPacketIndex = (zeroIndex) ? 0 : -1;
|
||||
isResending = true;
|
||||
msgToResendCurrent.clear();
|
||||
msgToResendCurrent.addAll(msgToResend);
|
||||
}
|
||||
|
||||
private boolean compareData(byte[] data1, byte[] data2) {
|
||||
if ((data1 == null && data2 != null) || (data1 != null && data2 == null)) return false;
|
||||
if (data1 == data2) return true;
|
||||
|
Loading…
Reference in New Issue
Block a user