Skip to content

Commit

Permalink
what a fatal and embarrassing bug in ASAPSerialization could be fixed…
Browse files Browse the repository at this point in the history
… now. Now we can exchange messages with a length greater than 255.
  • Loading branch information
thsc42 committed Jan 6, 2021
1 parent a8f3d62 commit bc9a28e
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 13 deletions.
5 changes: 2 additions & 3 deletions src/net/sharksystem/asap/protocol/AssimilationPDU_Impl.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ static void sendPDUWithoutCmd(CharSequence peer, CharSequence recipient, CharSeq
ASAPSerialization.writeCharSequenceParameter(channel, os); // opt
ASAPSerialization.writeNonNegativeIntegerParameter(era, os); // opt
ASAPSerialization.writeCharSequenceParameter(list2string(offsets), os); // opt

ASAPSerialization.writeNonNegativeLongParameter(length, os); // mand
ASAPSerialization.writeLongParameter(length, os); // mand

// stream data
while(length-- > 0) {
Expand Down Expand Up @@ -135,7 +134,7 @@ public List<Integer> getMessageOffsets() {

@Override
public byte[] getData() throws IOException {
if(data == null) {
if(this.data == null) {
if(this.dataNoLongerOnStream)
throw new IOException(this.getLogStart() + "data are already read from stream, probably with streamData");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Expand Down
86 changes: 78 additions & 8 deletions src/net/sharksystem/utils/ASAPSerialization.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
import java.util.Set;

public class ASAPSerialization {
public static final long BLANK_LEFT_LONG = 0x00000000FFFFFFFFL;
public static final long BLANK_RIGHT_LONG = 0xFFFFFFFF00000000L;
public static final int BLANK_LEFT_INTEGER = 0x0000FFFF;
public static final int BLANK_RIGHT_INTEGER = 0xFFFF0000;
public static final short BLANK_LEFT_SHORT = 0x00FF;
public static final short BLANK_RIGHT_SHORT = (short) 0xFF00;

public static void writeByteArray(byte[] bytes2Write, OutputStream os) throws IOException {
writeNonNegativeIntegerParameter(bytes2Write.length, os);
os.write(bytes2Write);
Expand Down Expand Up @@ -37,12 +44,14 @@ public static void writeByteParameter(byte parameter, OutputStream os) throws IO
os.write(new byte[] { parameter} );
}

public static void writeShortParameter(short parameter, OutputStream os) throws IOException {
public static void writeShortParameter(short shortValue, OutputStream os) throws IOException {
// short = 16 bit = 2 bytes
int leftInt = parameter >> 8;
writeByteParameter( (byte)leftInt, os);
short left = (short) (shortValue & BLANK_RIGHT_SHORT);
left = (short) (left >> 8);
short right = (short) (shortValue & BLANK_LEFT_SHORT);
writeByteParameter( (byte)left, os);
// cut left part
writeByteParameter( (byte)parameter, os);
writeByteParameter( (byte)right, os);
}

public static void writeNonNegativeIntegerParameter(int parameter, OutputStream os) throws IOException {
Expand All @@ -54,13 +63,53 @@ public static void writeNonNegativeIntegerParameter(int parameter, OutputStream
writeShortParameter((short) parameter, os);
}

public static void writeIntegerParameter(int intValue, OutputStream os) throws IOException {
// Integer == 32 bit == 4 Byte
int left = intValue & BLANK_RIGHT_INTEGER;
left = left >> 16;
int right = intValue & BLANK_LEFT_INTEGER;
writeShortParameter((short) left, os);
writeShortParameter((short) right, os);
}

public static void writeNonNegativeLongParameter(long longValue, OutputStream os) throws IOException {
if(longValue < 0) return;
if(longValue > -1) writeLongParameter(longValue, os);
}

public static void writeLongParameter(long longValue, OutputStream os) throws IOException {
// Long = 64 bit = 2 Integer
long left = longValue >> 32;
writeNonNegativeIntegerParameter((int) left, os);
writeNonNegativeIntegerParameter((int) longValue, os);
long left = longValue & BLANK_RIGHT_LONG;
left = left >> 32;
long right = longValue & BLANK_LEFT_LONG;
writeIntegerParameter((int)left, os);
writeIntegerParameter((int)right, os);
}

public static void printBits(long l, int bits) {
long mask = 1;
mask = mask << bits-1;
short byteBitCounter = 4;
while(mask != 0) {
if((l & mask) != 0) System.out.print("1");
else System.out.print("0");
if(--byteBitCounter == 0) {
byteBitCounter = 4;
System.out.print(" ");
}
mask = mask >> 1;
}
System.out.print(" ");
}

public static void printByte(short s) { printBits(s, 8); }
public static void printBits(short s) { printBits(s, 16); }
public static void printBits(int i) { printBits(i, 32); }
public static void printBits(long l) {
long left = l & BLANK_RIGHT_LONG;
left = left >> 32;
printBits((int) left);
long right = l & BLANK_LEFT_LONG;
printBits((int) right);
}

public static byte readByteParameter(InputStream is) throws IOException, ASAPException {
Expand All @@ -78,24 +127,45 @@ public static byte readByte(InputStream is) throws IOException, ASAPException {
public static short readShortParameter(InputStream is) throws IOException, ASAPException {
int value = readByteParameter(is);
value = value << 8;
// by sure
value = value & BLANK_RIGHT_SHORT;
int right = readByteParameter(is);
// by sure
right = right & BLANK_LEFT_SHORT;
value += right;

return (short) value;
}

public static int readIntegerParameter(InputStream is) throws IOException, ASAPException {
int value = readShortParameter(is);
value = value << 16;
value = value & BLANK_RIGHT_INTEGER;

int right = readShortParameter(is);
right = right & BLANK_LEFT_INTEGER;

value += right;

return value;
}

public static long readLongParameter(InputStream is) throws IOException, ASAPException {
long value = readIntegerParameter(is);
value = value << 32;
value = value & BLANK_RIGHT_LONG;

long right = readIntegerParameter(is);
right = right & BLANK_LEFT_LONG;

value += right;

/*
System.out.println("readLongParameter");
printBits(value);
System.out.print("\n");
*/

return value;
}

Expand Down
177 changes: 177 additions & 0 deletions test/net/sharksystem/asap/LongerMessages.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package net.sharksystem.asap;

import net.sharksystem.asap.util.ASAPChunkReceivedTester;
import net.sharksystem.asap.util.ASAPPeerHandleConnectionThread;
import net.sharksystem.cmdline.TCPStream;
import net.sharksystem.utils.ASAPSerialization;
import org.junit.Assert;
import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;

import static net.sharksystem.asap.ASAPPeer.DEFAULT_MAX_PROCESSING_TIME;

public class LongerMessages {
public static final String ALICE_BOB_CHAT_URL = "content://aliceAndBob.talk";
public static final String CHAT_FORMAT = "application/x-sn2-makan";
public static final String ALICE_ROOT_FOLDER = "longmessage/Alice";
public static final String ALICE_APP_FOLDER = ALICE_ROOT_FOLDER + "/appFolder";
public static final String BOB_ROOT_FOLDER = "longmessage/Bob";
public static final String BOB_APP_FOLDER = BOB_ROOT_FOLDER + "/appFolder";
public static final String ALICE = "Alice";
public static final String BOB = "Bob";
// 200
public static final String ALICE2BOB_MESSAGE = "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111";
//public static final String ALICE2BOB_MESSAGE = "Hi Bob";
//public static final String ALICE2BOB_MESSAGE2 = "HiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgain";
public static final String ALICE2BOB_MESSAGE2 = "Hi Again";

private static int portnumber = 7777;

private int getPortNumber() {
portnumber++;
return portnumber;
}

@Test
public void serializeDeserializeTest() throws IOException, ASAPException {
long writeLong = 0x9ABCDEF012345678L;
//long writeLong = 0x9999999999999999L;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ASAPSerialization.writeLongParameter(writeLong, baos);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
long readLong = ASAPSerialization.readLongParameter(bais);

Assert.assertEquals(writeLong, readLong);
}

@Test
public void longerMessagesAlice2Bob() throws IOException, ASAPException, InterruptedException {
///////////////////////////////////////////////////////////////////////////////////////////////////
// prepare storages //
///////////////////////////////////////////////////////////////////////////////////////////////////

ASAPEngineFS.removeFolder(ALICE_ROOT_FOLDER); // clean previous version before
ASAPEngineFS.removeFolder(BOB_ROOT_FOLDER); // clean previous version before

// alice writes a message into chunkStorage
ASAPStorage aliceStorage = ASAPEngineFS.getASAPStorage(ALICE, ALICE_APP_FOLDER, CHAT_FORMAT);

int aliceInitialEra = aliceStorage.getEra();

aliceStorage.createChannel(ALICE_BOB_CHAT_URL, BOB);

// content changed - next change in topology should increase alice era.
aliceStorage.add(ALICE_BOB_CHAT_URL, ALICE2BOB_MESSAGE);

// bob does the same
ASAPStorage bobStorage = ASAPEngineFS.getASAPStorage(BOB, BOB_APP_FOLDER, CHAT_FORMAT);

int bobInitialEra = bobStorage.getEra();

bobStorage.createChannel(ALICE_BOB_CHAT_URL, ALICE);

///////////////////////////////////////////////////////////////////////////////////////////////////
// prepare multi engines //
///////////////////////////////////////////////////////////////////////////////////////////////////

ASAPChunkReceivedTester aliceListener = new ASAPChunkReceivedTester();
ASAPPeer aliceEngine = ASAPPeerFS.createASAPPeer(
ALICE, ALICE_ROOT_FOLDER, DEFAULT_MAX_PROCESSING_TIME, aliceListener);

ASAPChunkReceivedTester bobListener = new ASAPChunkReceivedTester();
ASAPPeer bobEngine = ASAPPeerFS.createASAPPeer(
BOB, BOB_ROOT_FOLDER, DEFAULT_MAX_PROCESSING_TIME, bobListener);

///////////////////////////////////////////////////////////////////////////////////////////////////
// prepare asap immediate bypass //
///////////////////////////////////////////////////////////////////////////////////////////////////

ASAPAbstractOnlineMessageSender aliceBypass = new ASAPSingleProcessOnlineMessageSender(aliceEngine, aliceStorage);
ASAPAbstractOnlineMessageSender bobBypass = new ASAPSingleProcessOnlineMessageSender(bobEngine, bobStorage);

///////////////////////////////////////////////////////////////////////////////////////////////////
// setup connection //
///////////////////////////////////////////////////////////////////////////////////////////////////

int portNumber = this.getPortNumber();
// create connections for both sides
TCPStream aliceChannel = new TCPStream(portNumber, true, "a2b");
TCPStream bobChannel = new TCPStream(portNumber, false, "b2a");

aliceChannel.start();
bobChannel.start();

// wait to connect
aliceChannel.waitForConnection();
bobChannel.waitForConnection();

///////////////////////////////////////////////////////////////////////////////////////////////////
// run asap connection //
///////////////////////////////////////////////////////////////////////////////////////////////////

// run engine as thread
ASAPPeerHandleConnectionThread aliceEngineThread = new ASAPPeerHandleConnectionThread(aliceEngine,
aliceChannel.getInputStream(), aliceChannel.getOutputStream());

aliceEngineThread.start();

// and better debugging - no new thread
bobEngine.handleConnection(bobChannel.getInputStream(), bobChannel.getOutputStream());

// give handleConnection some time.
Thread.sleep(1000);
// create second message after creating a connection - should be bypassed.
//aliceStorage.add(ALICE_BOB_CHAT_URL, ALICE2BOB_MESSAGE2);

// wait until communication probably ends
System.out.flush();
System.err.flush();
Thread.sleep(2000);
System.out.flush();
System.err.flush();

// close connections: note ASAPEngine does NOT close any connection!!
aliceChannel.close();
bobChannel.close();
System.out.flush();
System.err.flush();
Thread.sleep(1000);
System.out.flush();
System.err.flush();

// check results

// listener must have been informed about new messages
Assert.assertTrue(bobListener.chunkReceived());


///////////////////////////////////////////////////////////////////////////////////////////////////
// open incoming storages //
///////////////////////////////////////////////////////////////////////////////////////////////////

// get message bob received
ASAPChunkStorage bobIncomingAliceStorage = bobStorage.getReceivedChunksStorage(ALICE);
ASAPChunk bobReceivedChunk = bobIncomingAliceStorage.getChunk(ALICE_BOB_CHAT_URL, aliceInitialEra);

// #1
Iterator<CharSequence> bobReceivedMessages = bobReceivedChunk.getMessagesAsCharSequence();
CharSequence bobReceivedMessage = bobReceivedMessages.next();
Assert.assertEquals(ALICE2BOB_MESSAGE, bobReceivedMessage);

// #2 - in next era
/*
bobReceivedChunk = bobIncomingAliceStorage.getChunk(ALICE_BOB_CHAT_URL, ASAP.nextEra(aliceInitialEra));
bobReceivedMessages = bobReceivedChunk.getMessagesAsCharSequence();
bobReceivedMessage = bobReceivedMessages.next();
Assert.assertEquals(ALICE2BOB_MESSAGE2, bobReceivedMessage);
*/

Thread.sleep(1000);
}

}
4 changes: 3 additions & 1 deletion test/net/sharksystem/asap/Point2PointTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ public class Point2PointTests {
public static final String ALICE = "Alice";
public static final String BOB = "Bob";
public static final String ALICE2BOB_MESSAGE = "Hi Bob";
public static final String ALICE2BOB_MESSAGE2 = "Hi Bob again";
// 400 characters
//public static final String ALICE2BOB_MESSAGE2 = "HiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgainHiYouAgain";
public static final String ALICE2BOB_MESSAGE2 = "Hi You Again";
public static final String BOB2ALICE_MESSAGE = "Hi Alice";
public static final String BOB2ALICE_MESSAGE2 = "Hi Alice again";

Expand Down
3 changes: 2 additions & 1 deletion test/net/sharksystem/asap/V1TestSuite.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
CreateNewChannelFromOutsideTest.class,
PDUTests.class,
CryptoTests.class,
SNMessageASAPSerializationTests.class
SNMessageASAPSerializationTests.class,
LongerMessages.class
})
public class V1TestSuite {

Expand Down

0 comments on commit bc9a28e

Please sign in to comment.