public void testResendAlreadyCompleted() throws BlockedTooLongException, InterruptedException { NullBasePeerNode senderNode = new NullBasePeerNode(); NewPacketFormat sender = new NewPacketFormat(senderNode, 0, 0); PeerMessageQueue senderQueue = new PeerMessageQueue(); NullBasePeerNode receiverNode = new NullBasePeerNode(); NewPacketFormat receiver = new NewPacketFormat(receiverNode, 0, 0); SessionKey senderKey = new SessionKey(null, null, null, null, null, null, null, null, new NewPacketFormatKeyContext(0, 0), 1); SessionKey receiverKey = new SessionKey(null, null, null, null, null, null, null, null, new NewPacketFormatKeyContext(0, 0), 1); senderQueue.queueAndEstimateSize(new MessageItem(new byte[128], null, false, null, (short) 0, false, false), 1024); Thread.sleep(PacketSender.MAX_COALESCING_DELAY*2); NPFPacket packet1 = sender.createPacket(512, senderQueue, senderKey, false); assertEquals(1, receiver.handleDecryptedPacket(packet1, receiverKey).size()); //Receiving the same packet twice should work assertEquals(0, receiver.handleDecryptedPacket(packet1, receiverKey).size()); //Same message, new sequence number ie. resend assertEquals(0, receiver.handleDecryptedPacket(packet1, receiverKey).size()); }
keyContext.seqNumWatchList[i] = NewPacketFormat.encryptSequenceNumber(seqNum++, sessionKey); if(seqNum < 0) seqNum = 0; if(seqNumGreaterThan(highestReceivedSeqNum, oldHighestReceived, 31)) { int moveBy; if(highestReceivedSeqNum > oldHighestReceived) { keyContext.seqNumWatchList[i % keyContext.seqNumWatchList.length] = encryptSequenceNumber(seqNum++, sessionKey); if(seqNum < 0) seqNum = 0; NPFPacket p = decipherFromSeqnum(buf, offset, length, sessionKey, sequenceNumber); if(p != null) { if(logMINOR) Logger.minor(this, "Received packet " + p.getSequenceNumber()+" on "+sessionKey);
@Override public boolean maybeSendPacket(long now, boolean ackOnly) throws BlockedTooLongException { SessionKey sessionKey = pn.getPreviousKeyTracker(); if(sessionKey != null) { // Try to sent an ack-only packet. if(maybeSendPacket(true, sessionKey)) return true; } sessionKey = pn.getUnverifiedKeyTracker(); if(sessionKey != null) { // Try to sent an ack-only packet. if(maybeSendPacket(true, sessionKey)) return true; } sessionKey = pn.getCurrentKeyTracker(); if(sessionKey == null) { Logger.warning(this, "No key for encrypting hash"); return false; } return maybeSendPacket(ackOnly, sessionKey); }
ret = Math.min(ret, timeCheckForAcks()); ret = Math.min(ret, now + Math.min(100, (long)averageRTT()/2));
public void testEmptyCreation() throws BlockedTooLongException { NewPacketFormat npf = new NewPacketFormat(null, 0, 0); PeerMessageQueue pmq = new PeerMessageQueue(); SessionKey s = new SessionKey(null, null, null, null, null, null, null, null, new NewPacketFormatKeyContext(0, 0), 1); NPFPacket p = npf.createPacket(1400, pmq, s, false); if(p != null) fail("Created packet from nothing"); }
new NewPacketFormat(senderNode, senderStartSeq, receiverStartSeq); NewPacketFormat receiverNPF = new NewPacketFormat(receiverNode, receiverStartSeq, senderStartSeq); senderNPF.maybeSendPacket(false, senderSessionKey); receiverNPF.handleReceivedPacket(data, 0, data.length, System.currentTimeMillis(), PEER);
NPFPacket createPacket(int maxPacketSize, PeerMessageQueue messageQueue, SessionKey sessionKey, boolean ackOnly) throws BlockedTooLongException { checkForLostPackets(); int maxSendBufferSize = maxSendBufferSize(); synchronized(sendBufferLock) { if(sendBufferUsed > maxSendBufferSize / 2) { cantSend = !canSend(sessionKey); checkedCanSend = true; if(!cantSend) { cantSend = !canSend(sessionKey); checkedCanSend = true; if(cantSend) { cantSend = !canSend(sessionKey); int messageID = getMessageID(); if(messageID == -1) {
packet = tryDecipherPacket(buf, offset, length, s); if(packet != null) { if(logDEBUG) Logger.debug(this, "Decrypted packet with tracker " + i); pn.reportIncomingBytes(length); List<byte[]> finished = handleDecryptedPacket(packet, s); if(logMINOR && !finished.isEmpty()) Logger.minor(this, "Decoded messages: "+finished.size());
NewPacketFormatKeyContext keyContext = sessionKey.packetContext; NPFPacket packet = createPacket(maxPacketSize - HMAC_LENGTH, pn.getMessageQueue(), sessionKey, ackOnly); if(packet == null) return false;
public void testSequenceNumberEncryption() { BlockCipher ivCipher = new Rijndael(); ivCipher.initialize(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); byte[] ivNonce = new byte[16]; BlockCipher incommingCipher = new Rijndael(); incommingCipher.initialize(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); SessionKey sessionKey = new SessionKey(null, null, null, incommingCipher, null, ivCipher, ivNonce, null, null, -1); byte[] encrypted = NewPacketFormat.encryptSequenceNumber(0, sessionKey); /* This result has not been checked, but it was the output when * this test was added and we are (in this test) only * interested in making sure the output doesn't change. */ byte[] correct = new byte[] {(byte) 0xF7, (byte) 0x95, (byte) 0xBD, (byte) 0x4A}; assertTrue(Arrays.equals(correct, encrypted)); }
timeLastSentPacket = now; if(packetFormat == null) { packetFormat = new NewPacketFormat(this, ourInitialMsgID, theirInitialMsgID);
@Override public long timeCheckForLostPackets() { long timeCheck = Long.MAX_VALUE; double averageRTT = averageRTT(); SessionKey key = pn.getCurrentKeyTracker(); if(key != null) timeCheck = Math.min(timeCheck, ((key.packetContext)).timeCheckForLostPackets(averageRTT)); key = pn.getPreviousKeyTracker(); if(key != null) timeCheck = Math.min(timeCheck, ((key.packetContext)).timeCheckForLostPackets(averageRTT)); key = pn.getUnverifiedKeyTracker(); if(key != null) timeCheck = Math.min(timeCheck, ((key.packetContext)).timeCheckForLostPackets(averageRTT)); return timeCheck; }
public void testLoadStatsLowLevel() throws BlockedTooLongException, InterruptedException { final byte[] loadMessage = new byte[] { (byte)0xFF, (byte)0xEE, (byte)0xDD, (byte)0xCC, (byte)0xBB, (byte)0xAA}; final SessionKey senderKey = new SessionKey(null, null, null, null, null, null, null, null, new NewPacketFormatKeyContext(0, 0), 1); NullBasePeerNode senderNode = new NullBasePeerNode() { @Override public MessageItem makeLoadStats(boolean realtime, boolean highPriority, boolean noRemember) { return new MessageItem(loadMessage, null, false, null, (short) 0, false, false); } @Override public SessionKey getCurrentKeyTracker() { return senderKey; } }; NewPacketFormat sender = new NewPacketFormat(senderNode, 0, 0); PeerMessageQueue senderQueue = new PeerMessageQueue(); senderQueue.queueAndEstimateSize(new MessageItem(new byte[128], null, false, null, (short) 0, false, true), 1024); Thread.sleep(PacketSender.MAX_COALESCING_DELAY*2); NPFPacket packet1 = sender.createPacket(512, senderQueue, senderKey, false); assertTrue(packet1 != null); assertEquals(1, packet1.getFragments().size()); assertEquals(1, packet1.getLossyMessages().size()); NPFPacketTest.checkEquals(loadMessage, packet1.getLossyMessages().get(0)); // Don't decode the packet because it's not a real message. }
@Override public void checkForLostPackets() { if(pn == null) return; double averageRTT = averageRTT(); long curTime = System.currentTimeMillis(); SessionKey key = pn.getCurrentKeyTracker(); if(key != null) ((key.packetContext)).checkForLostPackets(averageRTT, curTime, pn); key = pn.getPreviousKeyTracker(); if(key != null) ((key.packetContext)).checkForLostPackets(averageRTT, curTime, pn); key = pn.getUnverifiedKeyTracker(); if(key != null) ((key.packetContext)).checkForLostPackets(averageRTT, curTime, pn); }
public void testOutOfOrderDelivery() throws BlockedTooLongException { NullBasePeerNode senderNode = new NullBasePeerNode(); NewPacketFormat sender = new NewPacketFormat(senderNode, 0, 0); PeerMessageQueue senderQueue = new PeerMessageQueue(); NullBasePeerNode receiverNode = new NullBasePeerNode(); NewPacketFormat receiver = new NewPacketFormat(receiverNode, 0, 0); SessionKey senderKey = new SessionKey(null, null, null, null, null, null, null, null, new NewPacketFormatKeyContext(0, 0), 1); SessionKey receiverKey = new SessionKey(null, null, null, null, null, null, null, null, new NewPacketFormatKeyContext(0, 0), 1); senderQueue.queueAndEstimateSize(new MessageItem(new byte[1024], null, false, null, (short) 0, false, false), 1024); NPFPacket fragment1 = sender.createPacket(512, senderQueue, senderKey, false); assertEquals(1, fragment1.getFragments().size()); NPFPacket fragment2 = sender.createPacket(512, senderQueue, senderKey, false); assertEquals(1, fragment2.getFragments().size()); NPFPacket fragment3 = sender.createPacket(512, senderQueue, senderKey, false); assertEquals(1, fragment3.getFragments().size()); receiver.handleDecryptedPacket(fragment1, receiverKey); receiver.handleDecryptedPacket(fragment3, receiverKey); assertEquals(1, receiver.handleDecryptedPacket(fragment2, receiverKey).size()); }
public void testReceiveUnknownMessageLength() throws BlockedTooLongException { NullBasePeerNode senderNode = new NullBasePeerNode(); NewPacketFormat sender = new NewPacketFormat(senderNode, 0, 0); PeerMessageQueue senderQueue = new PeerMessageQueue(); NullBasePeerNode receiverNode = new NullBasePeerNode(); NewPacketFormat receiver = new NewPacketFormat(receiverNode, 0, 0); SessionKey senderKey = new SessionKey(null, null, null, null, null, null, null, null, new NewPacketFormatKeyContext(0, 0), 1); SessionKey receiverKey = new SessionKey(null, null, null, null, null, null, null, null, new NewPacketFormatKeyContext(0, 0), 1); senderQueue.queueAndEstimateSize(new MessageItem(new byte[1024], null, false, null, (short) 0, false, false), 1024); NPFPacket fragment1 = sender.createPacket(512, senderQueue, senderKey, false); assertEquals(1, fragment1.getFragments().size()); NPFPacket fragment2 = sender.createPacket(512, senderQueue, senderKey, false); assertEquals(1, fragment2.getFragments().size()); NPFPacket fragment3 = sender.createPacket(512, senderQueue, senderKey, false); assertEquals(1, fragment3.getFragments().size()); receiver.handleDecryptedPacket(fragment3, receiverKey); receiver.handleDecryptedPacket(fragment2, receiverKey); assertEquals(1, receiver.handleDecryptedPacket(fragment1, receiverKey).size()); }
public void testAckOnlyCreation() throws BlockedTooLongException, InterruptedException { BasePeerNode pn = new NullBasePeerNode(); NewPacketFormat npf = new NewPacketFormat(pn, 0, 0); PeerMessageQueue pmq = new PeerMessageQueue(); SessionKey s = new SessionKey(null, null, null, null, null, null, null, null, new NewPacketFormatKeyContext(0, 0), 1); NPFPacket p = null; //Packet that should be acked p = new NPFPacket(); p.addMessageFragment(new MessageFragment(true, false, true, 0, 8, 8, 0, new byte[] {(byte) 0x01, (byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF }, null)); assertEquals(1, npf.handleDecryptedPacket(p, s).size()); Thread.sleep(NewPacketFormatKeyContext.MAX_ACK_DELAY*2); p = npf.createPacket(1400, pmq, s, false); assertEquals(1, p.getAcks().size()); }
public void testLostLastAck() throws BlockedTooLongException, InterruptedException { NullBasePeerNode senderNode = new NullBasePeerNode(); NewPacketFormat sender = new NewPacketFormat(senderNode, 0, 0); PeerMessageQueue senderQueue = new PeerMessageQueue(); NullBasePeerNode receiverNode = new NullBasePeerNode(); NewPacketFormat receiver = new NewPacketFormat(receiverNode, 0, 0); PeerMessageQueue receiverQueue = new PeerMessageQueue(); SessionKey senderKey = new SessionKey(null, null, null, null, null, null, null, null, new NewPacketFormatKeyContext(0, 0), 1); NPFPacket fragment1 = sender.createPacket(512, senderQueue, senderKey, false); assertEquals(1, fragment1.getFragments().size()); receiver.handleDecryptedPacket(fragment1, receiverKey); NPFPacket fragment2 = sender.createPacket(512, senderQueue, senderKey, false); assertEquals(1, fragment2.getFragments().size()); receiver.handleDecryptedPacket(fragment2, receiverKey); NPFPacket ack1 = receiver.createPacket(512, receiverQueue, receiverKey, false); assertEquals(2, ack1.getAcks().size()); assertEquals(0, (int)ack1.getAcks().first()); assertEquals(1, (int)ack1.getAcks().last()); sender.handleDecryptedPacket(ack1, senderKey); NPFPacket fragment3 = sender.createPacket(512, senderQueue, senderKey, false); assertEquals(1, fragment3.getFragments().size()); receiver.handleDecryptedPacket(fragment3, receiverKey); Thread.sleep(NewPacketFormatKeyContext.MAX_ACK_DELAY*2); receiver.createPacket(512, senderQueue, receiverKey, false); //Sent, but lost NPFPacket resend1 = sender.createPacket(512, senderQueue, senderKey, false);
NewPacketFormat sender = new NewPacketFormat(senderNode, 0, 0); PeerMessageQueue senderQueue = new PeerMessageQueue(); NullBasePeerNode receiverNode = new NullBasePeerNode() { NewPacketFormat receiver = new NewPacketFormat(receiverNode, 0, 0); SessionKey senderKey = new SessionKey(null, null, null, null, null, null, null, null, new NewPacketFormatKeyContext(0, 0), 1); SessionKey receiverKey = new SessionKey(null, null, null, null, null, null, null, null, new NewPacketFormatKeyContext(0, 0), 1); NPFPacket packet1 = sender.createPacket(512, senderQueue, senderKey, false); assertEquals(1, packet1.getFragments().size()); assertEquals(1, packet1.getLossyMessages().size()); assert(!gotMessage.value); assertEquals(1, receiver.handleDecryptedPacket(packet1, receiverKey).size()); synchronized(gotMessage) { assert(gotMessage.value);