List of usage examples for io.netty.buffer ByteBuf readIntLE
public abstract int readIntLE();
From source file:com.ibasco.agql.protocols.valve.source.query.handlers.SourceQueryPacketAssembler.java
License:Open Source License
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { log.trace("SourcePacketHandler.channelRead() : START"); try {// www.j a va 2 s .c o m //Make sure we are only receiving an instance of DatagramPacket if (!(msg instanceof DatagramPacket)) { return; } final DatagramPacket packet = (DatagramPacket) msg; final ByteBuf data = ((DatagramPacket) msg).content(); //Verify size if (data.readableBytes() <= 5) { log.debug( "Not a valid datagram for processing. Size getTotalRequests needs to be at least more than or equal to 5 bytes. Discarding. (Readable Bytes: {})", data.readableBytes()); return; } //Try to read protocol header, determine if its a single packet or a split-packet int protocolHeader = data.readIntLE(); //If the packet arrived is single type, we can already forward it to the next handler if (protocolHeader == 0xFFFFFFFF) { //Pass the message to the succeeding handlers ctx.fireChannelRead(packet.retain()); return; } //If the packet is a split type...we need to process each succeeding read until we have a complete packet else if (protocolHeader == 0xFFFFFFFE) { final ByteBuf reassembledPacket = processSplitPackets(data, ctx.channel().alloc(), packet.sender()); //Check if we already have a reassembled packet if (reassembledPacket != null) { ctx.fireChannelRead(packet.replace(reassembledPacket)); return; } } //Packet is not being handled by any of our processors, discard else { log.debug("Not a valid protocol header. Discarding. (Header Received: Dec = {}, Hex = {})", protocolHeader, Integer.toHexString(protocolHeader)); return; } } catch (Exception e) { log.error(String.format("Error while processing packet for %s", ((DatagramPacket) msg).sender()), e); throw e; } finally { //Release the message ReferenceCountUtil.release(msg); } log.trace("SourcePacketHandler.channelRead() : END"); }
From source file:com.ibasco.agql.protocols.valve.source.query.handlers.SourceQueryPacketAssembler.java
License:Open Source License
/** * Process split-packet data/*from ww w. ja va2 s . c o m*/ * * @param data * The {@link ByteBuf} containing the split-packet data * @param allocator * The {@link ByteBufAllocator} used to create/allocate pooled buffers * * @return Returns a non-null {@link ByteBuf} if the split-packets have been assembled. Null if the * * @throws Exception */ private ByteBuf processSplitPackets(ByteBuf data, ByteBufAllocator allocator, InetSocketAddress senderAddress) throws Exception { int packetCount, packetNumber, requestId, splitSize, packetChecksum = 0; boolean isCompressed; //Start processing requestId = data.readIntLE(); //read the most significant bit is set isCompressed = ((requestId & 0x80000000) != 0); //The total number of packets in the response. packetCount = data.readByte(); //The number of the packet. Starts at 0. packetNumber = data.readByte(); //Create our key for this request (request id + sender ip) final SplitPacketKey key = new SplitPacketKey(requestId, senderAddress); log.debug("Processing split packet {}", key); log.debug( "Split Packet Received = (AbstractRequest {}, Packet Number {}, Packet Count {}, Is Compressed: {})", requestId, packetNumber, packetCount, isCompressed); //Try to retrieve the split packet container for this request (if existing) //If request is not yet on the map, create and retrieve SplitPacketContainer splitPackets = this.requestMap.computeIfAbsent(key, k -> new SplitPacketContainer(packetCount)); //As per protocol specs, the size is only present in the first packet of the response and only if the response is being compressed. //split size = Maximum size of packet before packet switching occurs. The default value is 1248 bytes (0x04E0 if (isCompressed) { splitSize = data.readIntLE(); packetChecksum = data.readIntLE(); } else { splitSize = data.readShortLE(); } //TODO: Handle compressed split packets int bufferSize = Math.min(splitSize, data.readableBytes()); byte[] splitPacket = new byte[bufferSize]; data.readBytes(splitPacket); //transfer the split data into this buffer //Add the split packet to the container splitPackets.addPacket(packetNumber, splitPacket); //Have we received all packets for this request? if (splitPackets.isComplete()) { log.debug( "Split Packets have all been successfully received from AbstractRequest {}. Re-assembling packets.", requestId); //Retrieve total split packets received based on their length int packetSize = splitPackets.getPacketSize(); //Allocate a new buffer to store the re-assembled packets final ByteBuf packetBuffer = allocator.buffer(packetSize); boolean done = false; try { //Start re-assembling split-packets from the container done = reassembleSplitPackets(splitPackets, packetBuffer, isCompressed, splitSize, packetChecksum); } catch (Exception e) { //If an error occurs during re-assembly, make sure we release the allocated buffer packetBuffer.release(); throw e; } finally { if (done) requestMap.remove(key); } return packetBuffer; } //Return null, indicating that we still don't have a complete packet return null; }
From source file:com.ibasco.agql.protocols.valve.source.query.handlers.SourceRconPacketDecoder.java
License:Open Source License
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { final String separator = "================================================================================================="; //TODO: Move all code logic below to SourceRconPacketBuilder log.debug(separator);/* w ww. ja va 2 s. c o m*/ log.debug(" ({}) DECODING INCOMING DATA : Bytes Received = {} {}", index.incrementAndGet(), in.readableBytes(), index.get() > 1 ? "[Continuation]" : ""); log.debug(separator); String desc = StringUtils.rightPad("Minimum allowable size?", PAD_SIZE); //Verify we have the minimum allowable size if (in.readableBytes() < 14) { log.debug(" [ ] {} = NO (Actual Readable Bytes: {})", desc, in.readableBytes()); return; } log.debug(" [x] {} = YES (Actual Readable Bytes: {})", desc, in.readableBytes()); //Reset if this happens to be not a valid source rcon packet in.markReaderIndex(); //Read and Verify size desc = StringUtils.rightPad("Bytes received at least => than the \"declared\" size?", PAD_SIZE); int size = in.readIntLE(); int readableBytes = in.readableBytes(); if (readableBytes < size) { log.debug(" [ ] {} = NO (Declared Size: {}, Actual Bytes Read: {})", desc, readableBytes, size); in.resetReaderIndex(); return; } log.debug(" [x] {} = YES (Declared Size: {}, Actual Bytes Read: {})", desc, readableBytes, size); //Read and verify request id desc = StringUtils.rightPad("Request Id within the valid range?", PAD_SIZE); int id = in.readIntLE(); if (!(id == -1 || id == SourceRconUtil.RCON_TERMINATOR_RID || SourceRconUtil.isValidRequestId(id))) { log.debug(" [ ] {} = NO (Actual: {})", desc, id); in.resetReaderIndex(); return; } log.debug(" [x] {} = YES (Actual: {})", desc, id); //Read and verify request type desc = StringUtils.rightPad("Valid response type?", PAD_SIZE); int type = in.readIntLE(); if (get(type) == null) { log.debug(" [ ] {} = NO (Actual: {})", desc, type); in.resetReaderIndex(); return; } log.debug(" [x] {} = YES (Actual: {} = {})", desc, type, SourceRconResponseType.get(type)); //Read and verify body desc = StringUtils.rightPad("Contains Body?", PAD_SIZE); int bodyLength = in.bytesBefore((byte) 0); String body = StringUtils.EMPTY; if (bodyLength <= 0) log.debug(" [ ] {} = NO", desc); else { body = in.readCharSequence(bodyLength, StandardCharsets.UTF_8).toString(); log.debug(" [x] {} = YES (Length: {}, Body: {})", desc, bodyLength, StringUtils.replaceAll(StringUtils.truncate(body, 30), "\n", "\\\\n")); } //Peek at the last two bytes and verify that they are null-bytes byte bodyTerminator = in.getByte(in.readerIndex()); byte packetTerminator = in.getByte(in.readerIndex() + 1); desc = StringUtils.rightPad("Contains TWO null-terminating bytes at the end?", PAD_SIZE); //Make sure the last two bytes are NULL bytes (request id: 999 is reserved for split packet responses) if ((bodyTerminator != 0 || packetTerminator != 0) && (id == SourceRconUtil.RCON_TERMINATOR_RID)) { log.debug("Skipping {} bytes", in.readableBytes()); in.skipBytes(in.readableBytes()); return; } else if (bodyTerminator != 0 || packetTerminator != 0) { log.debug(" [ ] {} = NO (Actual: Body Terminator = {}, Packet Terminator = {})", desc, bodyTerminator, packetTerminator); in.resetReaderIndex(); return; } else { log.debug(" [x] {} = YES (Actual: Body Terminator = {}, Packet Terminator = {})", desc, bodyTerminator, packetTerminator); //All is good, skip the last two bytes if (in.readableBytes() >= 2) in.skipBytes(2); } //At this point, we can now construct a packet log.debug(" [x] Status: PASS (Size = {}, Id = {}, Type = {}, Remaining Bytes = {}, Body Size = {})", size, id, type, in.readableBytes(), bodyLength); log.debug(separator); //Reset the index index.set(0); //Construct the response packet and send to the next handlers SourceRconResponsePacket responsePacket; //Did we receive a terminator packet? if (this.terminatingPacketsEnabled && id == SourceRconUtil.RCON_TERMINATOR_RID && StringUtils.isBlank(body)) { responsePacket = new SourceRconTermResponsePacket(); } else { responsePacket = SourceRconPacketBuilder.getResponsePacket(type); } if (responsePacket != null) { responsePacket.setSize(size); responsePacket.setId(id); responsePacket.setType(type); responsePacket.setBody(body); log.debug( "Decode Complete. Passing response for request id : '{}' to the next handler. Remaining bytes ({})", id, in.readableBytes()); out.add(responsePacket); } }
From source file:com.ibasco.agql.protocols.valve.source.query.logger.SourceLogListenHandler.java
License:Open Source License
@Override protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception { ByteBuf data = msg.content(); if (data.readableBytes() > 6 && data.readIntLE() == -1) { byte[] raw = new byte[data.readableBytes() - 2]; data.readBytes(raw);/* w w w .jav a 2s . co m*/ data.skipBytes(2); //Pass to the callback if (logEventCallback != null) logEventCallback.accept(new SourceLogEntry(new String(raw, Charsets.UTF_8), msg.sender())); } }
From source file:com.ibasco.agql.protocols.valve.source.query.packets.response.SourceChallengeResponsePacket.java
License:Open Source License
@Override public Integer toObject() { ByteBuf data = getPayloadBuffer(); Integer challengeNumber;//from w ww . j a v a 2s . c o m //Read the 32bit challenge number challengeNumber = data.readIntLE(); return challengeNumber; }
From source file:com.ibasco.agql.protocols.valve.source.query.packets.response.SourcePlayerResponsePacket.java
License:Open Source License
@Override public List<SourcePlayer> toObject() { ByteBuf data = getPayloadBuffer(); List<SourcePlayer> playerList = new ArrayList<>(); byte numOfPlayers = data.readByte(); for (int i = 0; i < numOfPlayers; i++) playerList.add(new SourcePlayer(data.readByte(), ByteBufUtils.readString(data, CharsetUtil.UTF_8), data.readIntLE(), Float.intBitsToFloat(data.readIntLE()))); return playerList; }
From source file:com.ibasco.agql.protocols.valve.source.query.SourcePacketBuilder.java
License:Open Source License
@Override public <T extends SourceServerPacket> T construct(ByteBuf data) { //Mark Index//from w w w. j a va 2 s .com data.markReaderIndex(); try { //Reset the index data.readerIndex(0); //Verify size if (data.readableBytes() < 5) throw new IllegalStateException( "Cannot continue processing buffer with less than or equal to 4 bytes"); //Read protocol header int protocolHeader = data.readIntLE(); //Check if this is a split packet if (protocolHeader == 0xFFFFFFFE) throw new IllegalStateException("Cannot construct a response from a partial/split packet."); //Verify that we have a valid header if (protocolHeader != 0xFFFFFFFF) throw new IllegalStateException("Protocol header not supported."); //Read packet header byte packetHeader = data.readByte(); //Read payload byte[] payload = new byte[data.readableBytes()]; data.readBytes(payload); //Verify if packet header is valid SourceServerPacket packet = createResponsePacketFromHeader(packetHeader); //If packet is empty, means the supplied packet header is not supported if (packet == null) return null; packet.setProtocolHeader(ByteUtils.byteArrayFromInteger(protocolHeader)); packet.setHeader(packetHeader); packet.setPayload(payload); return (T) packet; } finally { data.resetReaderIndex(); } }
From source file:com.ibasco.agql.protocols.valve.source.query.SourceRconPacketBuilder.java
License:Open Source License
@SuppressWarnings("unchecked") @Override/*from w ww . j a v a 2s. c o m*/ public <T extends SourceRconPacket> T construct(ByteBuf data) { try { if (data.readableBytes() < 14) { log.warn("Packet is less than 10 bytes. Unsupported packet."); if (log.isDebugEnabled()) log.debug("Unrecognized Packet: \n{}", ByteBufUtil.prettyHexDump(data)); return null; } //Remember the reader index data.markReaderIndex(); //Read from the listen data.readerIndex(0); int size = data.readIntLE(); int id = data.readIntLE(); int type = data.readIntLE(); String body = data.readCharSequence(data.readableBytes() - 2, StandardCharsets.UTF_8).toString(); SourceRconResponsePacket packet = getResponsePacket(type); if (packet != null) { //Ok, we have a valid response packet. Lets keep reading. packet.setId(id); packet.setSize(size); packet.setType(type); packet.setBody(body); return (T) packet; } } finally { //Reset the index data.resetReaderIndex(); } return null; }
From source file:nearenough.protocol.RtWireTest.java
License:Open Source License
@Test public void encodeEmptyMessage() { RtMessage msg = RtMessage.fromBytes(new byte[] { 0, 0, 0, 0 }); ByteBuf onWire = RtWire.toWire(msg); // Empty message will be a single uint32 assertThat(onWire.readableBytes(), equalTo(4)); assertThat(onWire.readIntLE(), equalTo(0)); }
From source file:nearenough.protocol.RtWireTest.java
License:Open Source License
@Test public void encodeSingleTagMessage() { byte[] value = new byte[64]; Arrays.fill(value, (byte) 'a'); RtMessage msg = RtMessage.builder().add(RtTag.CERT, value).build(); // Wire encoding is 4 (num_tags) + 4 (CERT) + 64 (CERT value) ByteBuf onWire = RtWire.toWire(msg); assertThat(onWire.readableBytes(), equalTo(72)); // num_tags//from w w w . ja va 2 s . co m assertThat(onWire.readIntLE(), equalTo(1)); // CERT tag assertThat(onWire.readInt(), equalTo(RtTag.CERT.wireEncoding())); // CERT value assertThat(onWire.readableBytes(), equalTo(value.length)); byte[] readValue = new byte[onWire.readableBytes()]; onWire.readBytes(readValue); assertArrayEquals(value, readValue); // Message was completely read assertThat(onWire.readableBytes(), equalTo(0)); }