private byte[] encrypt(CommunicationPacket packet, Destination destination) { PublicKey publicKey = destination.getPublicKey(); byte[] data = packet.toByteArray(); return Util.encrypt(data, publicKey); }
/** * Creates a <code>CommunicationPacket</code> from raw datagram data. The packet ID * is initialized from the input data.<br/> * Subclasses start reading at byte {@link #HEADER_LENGTH} after calling this constructor. * @param data */ protected CommunicationPacket(byte[] data) { super(data[5]); // byte 5 is the protocol version in a communication packet if (!isPrefixValid(data)) { byte[] prefix = Arrays.copyOf(data, PACKET_PREFIX.length); log.error("Packet prefix invalid. Expected: " + Arrays.toString(PACKET_PREFIX) + ", actual: " + Arrays.toString(prefix)); } checkPacketType(data[4]); packetId = new UniqueId(data, 6); sentSignal = new CountDownLatch(1); sentTime = -1; }
/** * Creates an <code>I2PBotePacket</code> from its byte array representation.<br/> * The header bytes determine whether <code>DataPacket</code> or a <code>CommunicationPacket</code> is created. * @param data * @throws MalformedPacketException If the byte array does not contain a valid <code>I2PBotePacket</code>. */ private static I2PBotePacket createPacket(byte[] data) throws MalformedPacketException { if (CommunicationPacket.isPrefixValid(data)) return CommunicationPacket.createPacket(data); else return DataPacket.createPacket(data); }
/** * Writes the Prefix, Version, Type, and Packet Id fields of a Communication Packet to * an {@link OutputStream}. * @param outputStream */ protected void writeHeader(OutputStream outputStream) throws IOException { outputStream.write(PACKET_PREFIX); outputStream.write((byte)getPacketTypeCode()); outputStream.write(getProtocolVersion()); outputStream.write(packetId.toByteArray()); }
/** This method actually sends a packet via the router */ private void send(ScheduledPacket scheduledPacket) throws InterruptedException { CommunicationPacket i2pBotePacket = scheduledPacket.data; byte[] bytes = i2pBotePacket.toByteArray(); PacketBatch batch = scheduledPacket.batch; boolean isBatchPacket = batch != null; log.debug("Sending " + (isBatchPacket?"":"non-") + "batch packet: [" + i2pBotePacket + "] to " + Util.toShortenedBase32(scheduledPacket.destination)); try { sendDatagram(bytes, scheduledPacket.destination); // set sentTime, update queue and sentLatch, fire packet listeners scheduledPacket.data.setSentTime(System.currentTimeMillis()); if (isBatchPacket) batch.decrementSentLatch(); scheduledPacket.decrementSentLatch(); } catch (Exception exc) { log.error("Can't send packet.", exc); // pause to avoid CPU hogging if the error doesn't go away TimeUnit.SECONDS.sleep(1); } }
public synchronized void putPacket(CommunicationPacket packet, Destination destination) { outgoingPackets.put(packet.getPacketId(), new PacketBatchItem(packet, destination)); sentSignal = new CountDownLatch((int)sentSignal.getCount() + 1); }
/** * Decrypts the <code>CommunicationPacket</code> inside this packet. * @throws DataFormatException * @throws MalformedPacketException */ private CommunicationPacket decrypt(I2PSession i2pSession) throws DataFormatException, MalformedPacketException { PrivateKey privateKey = i2pSession.getDecryptionKey(); byte[] decryptedData = Util.decrypt(payload, privateKey); return CommunicationPacket.createPacket(decryptedData); } }
/** * Waits for an amount of time that is long enough to keep the sending rate below <code>maxBandwidth<code>, * and until the current time is past <code>earliestSendTime</code>. * @param scheduledPacket */ private void doPacketDelay(ScheduledPacket scheduledPacket) throws InterruptedException { if (maxBandwidth > 0) { CommunicationPacket i2pBotePacket = scheduledPacket.data; int packetSizeBits = i2pBotePacket.getSize() * 8; int maxBWBitsPerSecond = maxBandwidth * 1024; long waitTimeMsecs = 1000L * packetSizeBits / maxBWBitsPerSecond; if (System.currentTimeMillis()+waitTimeMsecs < scheduledPacket.earliestSendTime) waitTimeMsecs = scheduledPacket.earliestSendTime; TimeUnit.MILLISECONDS.sleep(waitTimeMsecs); } }
private boolean hasTimedOut(CommunicationPacket request, long timeout) { long sentTime = request.getSentTime(); return sentTime>0 && hasTimedOut(sentTime, timeout); }
Class<? extends I2PBotePacket> packetType = decodePacketTypeCode(packetTypeCode); if (packetType==null || !CommunicationPacket.class.isAssignableFrom(packetType)) { Log log = new Log(CommunicationPacket.class);
@Override public void packetReceived(CommunicationPacket packet, Destination sender, long receiveTime) { BanList banList = BanList.getInstance(); banList.update(sender, packet); synchronized(peers) { if (banList.isBanned(sender)) { peers.remove(sender); return; } // respond to PeerListRequests if (packet instanceof PeerListRequest) { // send up to MAX_PEERS_TO_SEND high-reachability peers minus the sender itself List<Destination> peersToSend = new ArrayList<Destination>(); peersToSend.addAll(getGoodPeers(MAX_PEERS_TO_SEND)); peersToSend.remove(sender); PeerList response = new PeerList(peersToSend); log.debug("Sending a PeerList containing " + peersToSend.size() + " peers in response to a PeerListRequest from " + Util.toShortenedBase32(sender)); sendQueue.sendResponse(response, sender, packet.getPacketId()); } // If there are less than MAX_PEERS/2 peers, add the sender (which can be a relay peer or a DHT peer) // as a relay peer. The other MAX_PEERS/2 are reserved for peers from PeerListRequests since they are preferrable. if (peers.size() < MAX_PEERS/2) peers.add(new RelayPeer(sender)); } } }
/** * Creates a packet from a byte array and fires listeners. * @param packetData * @param sender */ private void dispatchPacket(byte[] packetData, Destination sender) { CommunicationPacket packet; try { packet = CommunicationPacket.createPacket(packetData); logPacket(packet, sender); firePacketReceivedEvent(packet, sender); } catch (MalformedPacketException e) { log.warn("Ignoring unparseable packet.", e); firePacketReceivedEvent(new MalformedCommunicationPacket(), sender); } }
int padBytes = maxSize - payload.getSize(); if (padBytes < 0) padBytes = 0;
@Test public void testCreateAndUnwrap() throws I2PSessionException, DataFormatException, MalformedPacketException { byte[] storeRequestBytes = storeRequest.toByteArray(); CommunicationPacket commPacket = relayRequestMulti; for (int i=0; i<destKeys.length; i++) { assertTrue(commPacket instanceof CommunicationPacket); RelayRequest relayRequest = (RelayRequest)commPacket; commPacket = decryptDataPacket(relayRequest, relayRequest.getNextDestination()); } assertArrayEquals(storeRequestBytes, commPacket.toByteArray()); }
@Override public void packetReceived(CommunicationPacket packet, Destination sender, long receiveTime) { if (packet instanceof ResponsePacket) { UniqueId packetId = packet.getPacketId(); for (PacketBatch batch: runningBatches) if (batch.contains(packetId)) { DataPacket payload = ((ResponsePacket)packet).getPayload(); if (payload != null) batch.addResponse(sender, payload); else batch.addResponse(sender, new EmptyResponse()); } } }
DeletionInfoPacket delInfo = new DeletionInfoPacket(); delInfo.put(dhtKey, delAuthorization); Collection<ResponsePacket> response = ResponsePacket.create(delInfo, StatusCode.OK, packet.getPacketId()); sendQueue.send(response, sender);