use of com.biglybt.core.networkmanager.impl.RawMessageImpl in project BiglyBT by BiglySoftware.
the class AZMessageFactory method createAZRawMessage.
/**
* Create the proper AZ raw message from the given base message.
* @param base_message to create from
* @return AZ raw message
*/
public static RawMessage createAZRawMessage(Message base_message, int padding_mode) {
byte[] id_bytes = base_message.getIDBytes();
byte version = base_message.getVersion();
DirectByteBuffer[] payload = base_message.getData();
int payload_size = 0;
for (int i = 0; i < payload.length; i++) {
payload_size += payload[i].remaining(bss);
}
// create and fill header buffer
DirectByteBuffer header;
if (version >= MESSAGE_VERSION_SUPPORTS_PADDING) {
boolean enable_padding = padding_mode != AZMessageEncoder.PADDING_MODE_NONE;
short padding_length;
if (enable_padding) {
if (padding_mode == AZMessageEncoder.PADDING_MODE_MINIMAL) {
padding_length = (short) (RandomUtils.nextInt(SMALL_PAD_MAX));
} else {
padding_length = (short) (RandomUtils.nextInt(payload_size > 256 ? SMALL_PAD_MAX : BIG_PAD_MAX));
}
if (padding_length == 0) {
enable_padding = false;
}
} else {
padding_length = 0;
}
byte flags = enable_padding ? (byte) 0x01 : (byte) 0x00;
int header_size = 4 + 4 + id_bytes.length + 1 + (enable_padding ? (2 + padding_length) : 0);
header = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_MSG_AZ_HEADER, header_size);
header.putInt(bss, header_size - 4 + payload_size);
header.putInt(bss, id_bytes.length);
header.put(bss, id_bytes);
byte version_and_flags = (byte) ((flags << 4) | version);
header.put(bss, version_and_flags);
if (enable_padding) {
byte[] padding = new byte[padding_length];
header.putShort(bss, padding_length);
header.put(bss, padding);
}
} else {
int header_size = 4 + 4 + id_bytes.length + 1;
header = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_MSG_AZ_HEADER, header_size);
header.putInt(bss, header_size - 4 + payload_size);
header.putInt(bss, id_bytes.length);
header.put(bss, id_bytes);
header.put(bss, version);
}
header.flip(bss);
DirectByteBuffer[] raw_buffs = new DirectByteBuffer[payload.length + 1];
raw_buffs[0] = header;
System.arraycopy(payload, 0, raw_buffs, 1, payload.length);
String message_id = base_message.getID();
// determine if a legacy BT message
LegacyData ld = (LegacyData) legacy_data.get(message_id);
if (ld != null) {
// legacy message, use pre-configured values
return new RawMessageImpl(base_message, raw_buffs, ld.priority, ld.is_no_delay, ld.to_remove);
}
// these should really be properties of the message...
int priority;
boolean no_delay = true;
if (message_id == AZMessage.ID_AZ_HANDSHAKE) {
// handshake needs to go out first - if not high then bitfield can get in front of it...
priority = RawMessage.PRIORITY_HIGH;
} else if (message_id == AZMessage.ID_AZ_HAVE) {
priority = RawMessage.PRIORITY_LOW;
no_delay = false;
} else {
// standard message, ensure that protocol messages have wire priority over data payload messages
priority = base_message.getType() == Message.TYPE_DATA_PAYLOAD ? RawMessage.PRIORITY_LOW : RawMessage.PRIORITY_NORMAL;
}
return new RawMessageImpl(base_message, raw_buffs, priority, no_delay, null);
}
use of com.biglybt.core.networkmanager.impl.RawMessageImpl in project BiglyBT by BiglySoftware.
the class BTMessageFactory method createBTRawMessage.
/**
* Create the proper BT raw message from the given base message.
* @param base_message to create from
* @return BT raw message
*/
public static RawMessage createBTRawMessage(Message base_message) {
if (base_message instanceof RawMessage) {
// used for handshake and keep-alive messages
return (RawMessage) base_message;
}
LegacyData ld = (LegacyData) legacy_data.get(base_message.getID());
if (ld == null) {
Debug.out("legacy message type id not found for [" + base_message.getID() + "]");
// message id type not found
return null;
}
DirectByteBuffer[] payload = base_message.getData();
int payload_size = 0;
for (int i = 0; i < payload.length; i++) {
payload_size += payload[i].remaining(DirectByteBuffer.SS_MSG);
}
DirectByteBuffer header = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_MSG_BT_HEADER, 5);
header.putInt(DirectByteBuffer.SS_MSG, 1 + payload_size);
header.put(DirectByteBuffer.SS_MSG, ld.bt_id);
header.flip(DirectByteBuffer.SS_MSG);
DirectByteBuffer[] raw_buffs = new DirectByteBuffer[payload.length + 1];
raw_buffs[0] = header;
System.arraycopy(payload, 0, raw_buffs, 1, payload.length);
return new RawMessageImpl(base_message, raw_buffs, ld.priority, ld.is_no_delay, ld.to_remove);
}
use of com.biglybt.core.networkmanager.impl.RawMessageImpl in project BiglyBT by BiglySoftware.
the class GenericMessageEncoder method encodeMessage.
@Override
public RawMessage[] encodeMessage(Message _message) {
GenericMessage message = (GenericMessage) _message;
DirectByteBuffer payload = message.getPayload();
if (message.isAlreadyEncoded()) {
return (new RawMessage[] { new RawMessageImpl(message, new DirectByteBuffer[] { payload }, RawMessage.PRIORITY_NORMAL, // send immediately
true, new Message[0]) });
} else {
DirectByteBuffer header = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_EXTERNAL, 4);
header.putInt(DirectByteBuffer.SS_MSG, payload.remaining(DirectByteBuffer.SS_MSG));
header.flip(DirectByteBuffer.SS_MSG);
return (new RawMessage[] { new RawMessageImpl(message, new DirectByteBuffer[] { header, payload }, RawMessage.PRIORITY_NORMAL, // send immediately
true, new Message[0]) });
}
}
use of com.biglybt.core.networkmanager.impl.RawMessageImpl in project BiglyBT by BiglySoftware.
the class HTTPNetworkConnection method encodePiece.
protected RawMessage[] encodePiece(Message message) {
last_http_activity_time = SystemTime.getCurrentTime();
BTPiece piece = (BTPiece) message;
List<pendingRequest> ready_requests = new ArrayList<>();
boolean found = false;
synchronized (outstanding_requests) {
if (destroyed) {
return (new RawMessage[] { getEmptyRawMessage(message) });
}
for (int i = 0; i < outstanding_requests.size(); i++) {
pendingRequest req = outstanding_requests.get(i);
if (req.getPieceNumber() == piece.getPieceNumber() && req.getStart() == piece.getPieceOffset() && req.getLength() == piece.getPieceData().remaining(DirectByteBuffer.SS_NET)) {
if (req.getBTPiece() == null) {
req.setBTPiece(piece);
found = true;
if (i == 0) {
Iterator<pendingRequest> it = outstanding_requests.iterator();
while (it.hasNext()) {
pendingRequest r = it.next();
BTPiece btp = r.getBTPiece();
if (btp == null) {
break;
}
it.remove();
ready_requests.add(r);
}
}
break;
}
}
}
}
if (!found) {
Debug.out("request not matched");
return (new RawMessage[] { getEmptyRawMessage(message) });
}
if (ready_requests.size() == 0) {
return (new RawMessage[] { getEmptyRawMessage(message) });
}
try {
submitBTRequests();
} catch (IOException e) {
}
pendingRequest req = (pendingRequest) ready_requests.get(0);
DirectByteBuffer[] buffers;
httpRequest http_request = req.getHTTPRequest();
RawMessage[] raw_messages = new RawMessage[ready_requests.size()];
for (int i = 0; i < raw_messages.length; i++) {
buffers = new DirectByteBuffer[2];
if (!http_request.hasSentFirstReply()) {
http_request.setSentFirstReply();
String header = encodeHeader(http_request);
buffers[0] = new DirectByteBuffer(ByteBuffer.wrap(header.getBytes()));
} else {
// we have to do this as core code assumes buffer entry 0 is protocol
buffers[0] = new DirectByteBuffer(ByteBuffer.allocate(0));
}
req = (pendingRequest) ready_requests.get(i);
BTPiece this_piece = req.getBTPiece();
int piece_number = this_piece.getPieceNumber();
if (!piece_map.get(piece_number)) {
// kinda crappy as it triggers on first block of piece, however better
// than nothing
piece_map.set(piece_number);
decoder.addMessage(new BTHave(piece_number, (byte) 1));
}
buffers[1] = this_piece.getPieceData();
req.logQueued();
if (request_listeners != null) {
Iterator<requestListener> it = request_listeners.iterator();
while (it.hasNext()) {
((requestListener) it.next()).requestComplete(req);
}
}
raw_messages[i] = new RawMessageImpl(this_piece, buffers, RawMessage.PRIORITY_HIGH, true, new Message[0]);
}
return (raw_messages);
}
Aggregations