use of net.i2p.data.ByteArray in project i2p.i2p by i2p.
the class FragmentedMessage method receive.
/**
* Receive the first fragment (#0) and related metadata. This may not be the first
* one to arrive at the endpoint however.
*
* @param payload data for the fragment non-null
* @param offset index into the payload where the fragment data starts (past headers/etc)
* @param length how much past the offset should we snag?
* @param isLast is this the last fragment in the message?
* @param toRouter what router is this destined for (may be null)
* @param toTunnel what tunnel is this destined for (may be null)
*/
public boolean receive(byte[] payload, int offset, int length, boolean isLast, Hash toRouter, TunnelId toTunnel) {
if (length <= 0 || length > MAX_FRAGMENT_SIZE) {
if (_log.shouldLog(Log.WARN))
_log.warn("Length is impossible (" + length + ") for messageId " + _messageId);
return false;
}
if (offset + length > payload.length) {
if (_log.shouldLog(Log.WARN))
_log.warn("Length is impossible (" + length + "/" + offset + " out of " + payload.length + ") for messageId " + _messageId);
return false;
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Receive message " + _messageId + " with " + length + " bytes (last? " + isLast + ") targetting " + toRouter + " / " + toTunnel + " offset=" + offset);
// new ByteArray(payload, offset, length); // new byte[length]);
ByteArray ba = _cache.acquire();
System.arraycopy(payload, offset, ba.getData(), 0, length);
ba.setValid(length);
ba.setOffset(0);
// System.arraycopy(payload, offset, ba.getData(), 0, length);
// if (_log.shouldLog(Log.DEBUG))
// _log.debug("fragment[0/" + offset + "/" + length + "]: "
// + Base64.encode(ba.getData(), ba.getOffset(), ba.getValid()));
_fragments[0] = ba;
_lastReceived = _lastReceived || isLast;
_toRouter = toRouter;
_toTunnel = toTunnel;
if (_highFragmentNum < 0)
_highFragmentNum = 0;
return true;
}
use of net.i2p.data.ByteArray in project i2p.i2p by i2p.
the class FragmentedMessage method releaseFragments.
/**
* Called as one of the endpoints for the tunnel cache pipeline (see TunnelDataMessage)
*/
private void releaseFragments() {
if (_releasedAfter > 0) {
RuntimeException e = new RuntimeException("double free in FragmentedMessage");
_log.error("FM releaseFragments()", e);
throw e;
}
_releasedAfter = getLifetime();
for (int i = 0; i <= _highFragmentNum; i++) {
ByteArray ba = _fragments[i];
if ((ba != null) && (ba.getData().length == TrivialPreprocessor.PREPROCESSED_SIZE)) {
_cache.release(ba);
_fragments[i] = null;
}
}
}
use of net.i2p.data.ByteArray in project i2p.i2p by i2p.
the class InboundEstablishState method generateSessionKey.
/**
* Generates session key and mac key.
*/
public synchronized void generateSessionKey() throws DHSessionKeyBuilder.InvalidPublicParameterException {
if (_sessionKey != null)
return;
_keyBuilder.setPeerPublicValue(_receivedX);
_sessionKey = _keyBuilder.getSessionKey();
ByteArray extra = _keyBuilder.getExtraBytes();
_macKey = new SessionKey(new byte[SessionKey.KEYSIZE_BYTES]);
System.arraycopy(extra.getData(), 0, _macKey.getData(), 0, SessionKey.KEYSIZE_BYTES);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Established inbound keys. cipher: " + Base64.encode(_sessionKey.getData()) + " mac: " + Base64.encode(_macKey.getData()));
}
use of net.i2p.data.ByteArray in project i2p.i2p by i2p.
the class InboundMessageState method receiveFragment.
/**
* Read in the data from the fragment.
* Caller should synchronize.
*
* @return true if the data was ok, false if it was corrupt
*/
public boolean receiveFragment(UDPPacketReader.DataReader data, int dataFragment) throws DataFormatException {
int fragmentNum = data.readMessageFragmentNum(dataFragment);
if ((fragmentNum < 0) || (fragmentNum >= _fragments.length)) {
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid fragment " + fragmentNum + '/' + _fragments.length);
return false;
}
if (_fragments[fragmentNum] == null) {
// new fragment, read it
ByteArray message = _fragmentCache.acquire();
try {
data.readMessageFragment(dataFragment, message.getData(), 0);
int size = data.readMessageFragmentSize(dataFragment);
if (size <= 0) {
// If we don't ack the fragment he will just send a zero-length fragment again.
if (_log.shouldLog(Log.WARN))
_log.warn("Zero-length fragment " + fragmentNum + " for message " + _messageId + " from " + _from);
}
message.setValid(size);
_fragments[fragmentNum] = message;
boolean isLast = data.readMessageIsLast(dataFragment);
if (isLast) {
// don't allow _lastFragment to be set twice
if (_lastFragment >= 0) {
if (_log.shouldLog(Log.ERROR))
_log.error("Multiple last fragments for message " + _messageId + " from " + _from);
return false;
}
// TODO - check for non-last fragments after this one?
_lastFragment = fragmentNum;
} else if (_lastFragment >= 0 && fragmentNum >= _lastFragment) {
// don't allow non-last after last
if (_log.shouldLog(Log.ERROR))
_log.error("Non-last fragment " + fragmentNum + " when last is " + _lastFragment + " for message " + _messageId + " from " + _from);
return false;
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("New fragment " + fragmentNum + " for message " + _messageId + ", size=" + size + ", isLast=" + isLast);
} catch (ArrayIndexOutOfBoundsException aioobe) {
if (_log.shouldLog(Log.WARN))
_log.warn("Corrupt SSU fragment " + fragmentNum, aioobe);
return false;
}
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Received fragment " + fragmentNum + " for message " + _messageId + " again, old size=" + _fragments[fragmentNum].getValid() + " and new size=" + data.readMessageFragmentSize(dataFragment));
}
return true;
}
use of net.i2p.data.ByteArray in project i2p.i2p by i2p.
the class OutboundEstablishState method generateSessionKey.
/**
* Generates session key and mac key.
* Caller must synch on this.
*/
private void generateSessionKey() throws DHSessionKeyBuilder.InvalidPublicParameterException {
if (_sessionKey != null)
return;
if (_keyBuilder == null)
throw new DHSessionKeyBuilder.InvalidPublicParameterException("Illegal state - never generated a key builder");
_keyBuilder.setPeerPublicValue(_receivedY);
_sessionKey = _keyBuilder.getSessionKey();
ByteArray extra = _keyBuilder.getExtraBytes();
_macKey = new SessionKey(new byte[SessionKey.KEYSIZE_BYTES]);
System.arraycopy(extra.getData(), 0, _macKey.getData(), 0, SessionKey.KEYSIZE_BYTES);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Established outbound keys. cipher: " + _sessionKey + " mac: " + _macKey);
}
Aggregations