use of i2p.bote.packet.CommunicationPacket in project i2p.i2p-bote by i2p.
the class RelayRequest method create.
/**
* Creates a <code>RelayRequest</code> containing <code>numHops</code> nested
* <code>RelayRequest</code>s<br/>
* Returns <code>null</code> if <code>numHops</code> is <code>0</code>.
* @param payload
* @param peerManager For obtaining relay peers
* @param numHops
* @param minDelay The minimum delay in milliseconds
* @param maxDelay The maximum delay in milliseconds
*/
public static RelayRequest create(CommunicationPacket payload, RelayPeerManager peerManager, int numHops, long minDelay, long maxDelay) {
List<Destination> relayPeers = peerManager.getRandomPeers(numHops);
Log log = new Log(RelayRequest.class);
if (log.shouldLog(Log.DEBUG)) {
StringBuilder debugMsg = new StringBuilder("Creating relay chain: [");
for (int i = relayPeers.size() - 1; i >= 0; i--) {
debugMsg.append(Util.toShortenedBase32(relayPeers.get(i)));
if (i > 0)
debugMsg.append(" --> ");
}
debugMsg.append("]");
log.debug(debugMsg.toString());
}
// calculate the number of pad bytes necessary to pad the payload to the maximum size possible
int maxSize = I2PBotePacket.MAX_DATAGRAM_SIZE - getMaxOverhead(numHops);
int padBytes = maxSize - payload.getSize();
if (padBytes < 0)
padBytes = 0;
CommunicationPacket request = payload;
for (Destination relayPeer : relayPeers) {
// generate a random time between minDelay and maxDelay in the future
long delay;
if (minDelay == maxDelay)
delay = minDelay;
else
delay = minDelay + Math.abs(random.nextLong()) % Math.abs(maxDelay - minDelay);
request = new RelayRequest(request, relayPeer, delay, padBytes);
// only pad the innermost packet (the payload)
padBytes = 0;
}
return (RelayRequest) request;
}
use of i2p.bote.packet.CommunicationPacket in project i2p.i2p-bote by i2p.
the class I2PPacketDispatcher method dispatchPacket.
/**
* 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);
}
}
use of i2p.bote.packet.CommunicationPacket in project i2p.i2p-bote by i2p.
the class I2PSendQueue method doPacketDelay.
/**
* 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);
}
}
use of i2p.bote.packet.CommunicationPacket in project i2p.i2p-bote by i2p.
the class RelayPacketHandler method packetReceived.
@Override
public void packetReceived(CommunicationPacket packet, Destination sender, long receiveTime) {
if (packet instanceof RelayRequest && dht.isReady()) {
RelayRequest relayRequest = (RelayRequest) packet;
CommunicationPacket payload;
try {
payload = relayRequest.getStoredPacket(i2pSession);
} catch (DataFormatException e) {
log.error("Invalid RelayRequest received from peer " + Util.toBase32(sender), e);
return;
} catch (MalformedPacketException e) {
log.error("Invalid RelayRequest received from peer " + Util.toBase32(sender), e);
return;
}
log.debug("Received a relay request, payload: " + payload);
if (payload instanceof RelayRequest) {
log.debug("Relay packet is of type " + payload.getClass().getSimpleName() + ", storing it in the relay packet folder.");
relayPacketFolder.add((RelayRequest) payload);
confirm(sender, relayRequest);
} else if (payload instanceof StoreRequest) {
log.debug("Relay packet is of type " + payload.getClass().getSimpleName() + ", storing it in the DHT.");
final DhtStorablePacket dhtPacket = ((StoreRequest) payload).getPacketToStore();
// do dht.store() in a separate thread so we don't block the notifier thread
dhtTaskExecutor.submit(new Runnable() {
@Override
public void run() {
try {
dht.store(dhtPacket);
log.debug("Finished storing DHT packet: " + dhtPacket);
} catch (InterruptedException e) {
log.debug("Interrupted while storing packet in the DHT.");
} catch (DhtException e) {
log.error("Error storing packet in the DHT: " + dhtPacket, e);
}
}
});
confirm(sender, relayRequest);
} else
log.error("Don't know how to handle relay packet of type " + payload.getClass());
}
}
use of i2p.bote.packet.CommunicationPacket in project i2p.i2p-bote by i2p.
the class RelayRequestTest method testCreateAndUnwrap.
@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());
}
Aggregations