use of com.biglybt.pifimpl.local.utils.PooledByteBufferImpl in project BiglyBT by BiglySoftware.
the class DiskManagerImpl method write.
@Override
public DiskManagerWriteRequest write(final int piece_number, final int offset, PooledByteBuffer data, final DiskManagerWriteRequestListener listener) throws DiskManagerException {
DirectByteBuffer buffer = ((PooledByteBufferImpl) data).getBuffer();
if (!disk_manager.checkBlockConsistencyForWrite("plugin", piece_number, offset, buffer)) {
throw (new DiskManagerException("write invalid - parameters incorrect"));
}
final int length = buffer.remaining(DirectByteBuffer.SS_EXTERNAL);
final DMWR request = new DMWR(disk_manager.createWriteRequest(piece_number, offset, buffer, null), length);
disk_manager.enqueueWriteRequest(request.getDelegate(), new com.biglybt.core.disk.DiskManagerWriteRequestListener() {
@Override
public void writeCompleted(com.biglybt.core.disk.DiskManagerWriteRequest _request) {
DiskManagerPiece[] dm_pieces = disk_manager.getPieces();
DiskManagerPiece dm_piece = dm_pieces[piece_number];
if (!dm_piece.isDone()) {
int current_offset = offset;
for (int i = 0; i < length; i += DiskManager.BLOCK_SIZE) {
dm_piece.setWritten(current_offset / DiskManager.BLOCK_SIZE);
current_offset += DiskManager.BLOCK_SIZE;
}
}
listener.complete(request);
}
@Override
public void writeFailed(com.biglybt.core.disk.DiskManagerWriteRequest _request, Throwable _cause) {
listener.failed(request, new DiskManagerException("read failed", _cause));
}
});
return (request);
}
use of com.biglybt.pifimpl.local.utils.PooledByteBufferImpl in project BiglyBT by BiglySoftware.
the class SESTSConnectionImpl method sendContent.
protected void sendContent(PooledByteBuffer message) throws MessageException {
if (outgoing_cipher != null) {
try {
byte[] plain = message.toByteArray();
byte[] enc = outgoing_cipher.doFinal(plain);
PooledByteBuffer temp = new PooledByteBufferImpl(enc);
try {
connection.send(temp);
// successfull send -> release caller's buffer
message.returnToPool();
} catch (Throwable e) {
// failed semantics are to not release the caller's buffer
temp.returnToPool();
throw (e);
}
} catch (Throwable e) {
throw (new MessageException("Failed to encrypt data", e));
}
} else {
if (block_crypto != SESecurityManager.BLOCK_ENCRYPTION_NONE) {
connection.close();
throw (new MessageException("Crypto isn't setup"));
}
connection.send(message);
}
}
use of com.biglybt.pifimpl.local.utils.PooledByteBufferImpl in project BiglyBT by BiglySoftware.
the class SESTSConnectionImpl method receiveContent.
protected void receiveContent(PooledByteBuffer message) throws MessageException {
boolean buffer_handled = false;
try {
if (incoming_cipher != null) {
try {
byte[] enc = message.toByteArray();
byte[] plain = incoming_cipher.doFinal(enc);
PooledByteBuffer temp = new PooledByteBufferImpl(plain);
message.returnToPool();
buffer_handled = true;
message = temp;
} catch (Throwable e) {
throw (new MessageException("Failed to decrypt data", e));
}
} else if (block_crypto != SESecurityManager.BLOCK_ENCRYPTION_NONE) {
throw (new MessageException("Crypto isn't setup"));
}
List listeners_ref = listeners.getList();
MessageException last_error = null;
for (int i = 0; i < listeners_ref.size(); i++) {
PooledByteBuffer message_to_deliver;
if (i == 0) {
message_to_deliver = message;
} else {
// unlikely we'll ever have > 1 receiver....
message_to_deliver = new PooledByteBufferImpl(message.toByteArray());
}
try {
((GenericMessageConnectionListener) listeners_ref.get(i)).receive(this, message_to_deliver);
if (message_to_deliver == message) {
buffer_handled = true;
}
} catch (Throwable e) {
message_to_deliver.returnToPool();
if (message_to_deliver == message) {
buffer_handled = true;
}
if (e instanceof MessageException) {
last_error = (MessageException) e;
} else {
last_error = new MessageException("Failed to process message", e);
}
}
}
if (last_error != null) {
throw (last_error);
}
} finally {
if (!buffer_handled) {
message.returnToPool();
}
}
}
use of com.biglybt.pifimpl.local.utils.PooledByteBufferImpl in project BiglyBT by BiglySoftware.
the class SESTSConnectionImpl method receive.
public void receive(PooledByteBuffer message) throws MessageException {
try {
boolean forward = false;
boolean crypto_completed = false;
ByteBuffer out_buffer = null;
synchronized (this) {
if (crypto_complete.isReleasedForever()) {
forward = true;
} else {
// basic sts flow:
// a -> puba -> b
// a <- pubb <- b
// a -> auta -> b
// a <- autb <- b
// a -> data -> b
// optimised
// a -> puba -> b
// a <- pubb + auta <- b
// a -> autb + data -> b
// therefore can be one or two messages in the payload
// 1 crypto
// 2 crypto (pub + auth)
// crypto + data
// initial a ->puba -> is done on first data send so data is ready for phase 3
ByteBuffer in_buffer = ByteBuffer.wrap(message.toByteArray());
message.returnToPool();
if (!sent_keys) {
// we've received
// a -> puba -> b
// reply with
// a <- puba + auta <- b
out_buffer = ByteBuffer.allocate(64 * 1024);
// write our keys
sts_engine.getKeys(out_buffer);
sent_keys = true;
// read their keys
sts_engine.putKeys(in_buffer);
// write our auth
sts_engine.getAuth(out_buffer);
sent_auth = true;
} else if (!sent_auth) {
out_buffer = ByteBuffer.allocate(64 * 1024);
// we've received
// a <- puba + auta <- b
// reply with
// a -> autb + data -> b
// read their keys
sts_engine.putKeys(in_buffer);
// write our auth
sts_engine.getAuth(out_buffer);
sent_auth = true;
// read their auth
sts_engine.putAuth(in_buffer);
// check we wanna talk to this person
byte[] rem_key = sts_engine.getRemotePublicKey();
if (!key_locator.accept(SESTSConnectionImpl.this, new SEPublicKeyImpl(my_public_key.getType(), rem_key))) {
throw (new MessageException("remote public key not accepted"));
}
setupBlockCrypto();
if (pending_message != null) {
byte[] pending_bytes = pending_message.toByteArray();
int pending_size = pending_bytes.length;
if (outgoing_cipher != null) {
pending_size = ((pending_size + AES_KEY_SIZE_BYTES - 1) / AES_KEY_SIZE_BYTES) * AES_KEY_SIZE_BYTES;
if (pending_size == 0) {
pending_size = AES_KEY_SIZE_BYTES;
}
}
if (out_buffer.remaining() >= pending_size) {
if (outgoing_cipher != null) {
out_buffer.put(outgoing_cipher.doFinal(pending_bytes));
} else {
out_buffer.put(pending_bytes);
}
// don't deallocate the pending message, the original caller does this
pending_message = null;
}
}
crypto_completed = true;
} else {
// we've received
// a -> autb + data -> b
// read their auth
sts_engine.putAuth(in_buffer);
// check we wanna talk to this person
byte[] rem_key = sts_engine.getRemotePublicKey();
if (!key_locator.accept(SESTSConnectionImpl.this, new SEPublicKeyImpl(my_public_key.getType(), rem_key))) {
// this is just here to prevent unwanted spew during closedown process
connection.closing();
throw (new MessageException("remote public key not accepted"));
}
setupBlockCrypto();
crypto_completed = true;
if (in_buffer.hasRemaining()) {
message = new PooledByteBufferImpl(new DirectByteBuffer(in_buffer.slice()));
forward = true;
}
}
}
}
if (out_buffer != null) {
out_buffer.flip();
connection.send(new PooledByteBufferImpl(new DirectByteBuffer(out_buffer)));
}
if (crypto_completed) {
cryptoComplete();
}
if (forward) {
receiveContent(message);
}
} catch (Throwable e) {
reportFailed(e);
if (e instanceof MessageException) {
throw ((MessageException) e);
} else {
throw (new MessageException("Receive failed", e));
}
}
}
use of com.biglybt.pifimpl.local.utils.PooledByteBufferImpl in project BiglyBT by BiglySoftware.
the class GenericMessageConnectionImpl method receive.
protected void receive(GenericMessage message) {
boolean handled = false;
for (int i = 0; i < listeners.size(); i++) {
PooledByteBuffer buffer = new PooledByteBufferImpl(message.getPayload());
try {
((GenericMessageConnectionListener) listeners.get(i)).receive(this, buffer);
handled = true;
} catch (Throwable f) {
buffer.returnToPool();
if (!(f instanceof MessageException)) {
Debug.printStackTrace(f);
}
}
}
if (!handled && !(closed || closing)) {
Debug.out("GenericMessage: incoming message not handled");
}
}
Aggregations