Example usage for io.netty.buffer ByteBuf readerIndex

List of usage examples for io.netty.buffer ByteBuf readerIndex

Introduction

In this page you can find the example usage for io.netty.buffer ByteBuf readerIndex.

Prototype

public abstract ByteBuf readerIndex(int readerIndex);

Source Link

Document

Sets the readerIndex of this buffer.

Usage

From source file:com.digitalpetri.opcua.stack.ChunkSerializationTest.java

License:Apache License

@Test(dataProvider = "getAsymmetricSecurityParameters")
public void testAsymmetricMessage(SecurityPolicy securityPolicy, MessageSecurityMode messageSecurity,
        int messageSize) throws Exception {

    logger.info("Asymmetric chunk serialization, securityPolicy={}, messageSecurityMode={}, messageSize={}",
            securityPolicy, messageSecurity, messageSize);

    ChunkEncoder encoder = new ChunkEncoder(parameters);
    ChunkDecoder decoder = new ChunkDecoder(parameters);

    SecureChannel[] channels = generateChannels(securityPolicy, messageSecurity);
    ClientSecureChannel clientChannel = (ClientSecureChannel) channels[0];
    ServerSecureChannel serverChannel = (ServerSecureChannel) channels[1];

    clientChannel.attr(ClientSecureChannel.KEY_REQUEST_ID_SEQUENCE)
            .setIfAbsent(new LongSequence(1L, UInteger.MAX_VALUE));

    LongSequence requestId = clientChannel.attr(ClientSecureChannel.KEY_REQUEST_ID_SEQUENCE).get();

    byte[] messageBytes = new byte[messageSize];
    for (int i = 0; i < messageBytes.length; i++) {
        messageBytes[i] = (byte) i;
    }//from ww  w.j a v  a2  s .c  o  m

    ByteBuf messageBuffer = BufferUtil.buffer().writeBytes(messageBytes);

    List<ByteBuf> chunkBuffers = encoder.encodeAsymmetric(clientChannel, MessageType.OpenSecureChannel,
            messageBuffer, requestId.getAndIncrement());

    ByteBuf decodedBuffer = decoder.decodeAsymmetric(serverChannel, chunkBuffers);

    ReferenceCountUtil.releaseLater(messageBuffer);
    ReferenceCountUtil.releaseLater(decodedBuffer);

    messageBuffer.readerIndex(0);
    assertEquals(decodedBuffer, messageBuffer);
}

From source file:com.digitalpetri.opcua.stack.ChunkSerializationTest.java

License:Apache License

@Test(dataProvider = "getSymmetricSecurityParameters")
public void testSymmetricMessage(SecurityPolicy securityPolicy, MessageSecurityMode messageSecurity,
        int messageSize) throws Exception {

    logger.info("Symmetric chunk serialization, securityPolicy={}, messageSecurityMode={}, messageSize={}",
            securityPolicy, messageSecurity, messageSize);

    ChunkEncoder encoder = new ChunkEncoder(parameters);
    ChunkDecoder decoder = new ChunkDecoder(parameters);

    SecureChannel[] channels = generateChannels(securityPolicy, messageSecurity);
    ClientSecureChannel clientChannel = (ClientSecureChannel) channels[0];
    ServerSecureChannel serverChannel = (ServerSecureChannel) channels[1];

    clientChannel.attr(ClientSecureChannel.KEY_REQUEST_ID_SEQUENCE)
            .setIfAbsent(new LongSequence(1L, UInteger.MAX_VALUE));

    LongSequence requestId = clientChannel.attr(ClientSecureChannel.KEY_REQUEST_ID_SEQUENCE).get();

    byte[] messageBytes = new byte[messageSize];
    for (int i = 0; i < messageBytes.length; i++) {
        messageBytes[i] = (byte) i;
    }//w  ww.j  a  v  a2  s.  c  o  m

    ByteBuf messageBuffer = BufferUtil.buffer().writeBytes(messageBytes);

    List<ByteBuf> chunkBuffers = encoder.encodeSymmetric(clientChannel, MessageType.SecureMessage,
            messageBuffer, requestId.getAndIncrement());

    ByteBuf decodedBuffer = decoder.decodeSymmetric(serverChannel, chunkBuffers);

    ReferenceCountUtil.releaseLater(messageBuffer);
    ReferenceCountUtil.releaseLater(decodedBuffer);

    messageBuffer.readerIndex(0);
    assertEquals(decodedBuffer, messageBuffer);
}

From source file:com.digitalpetri.opcua.stack.client.handlers.UaTcpClientAsymmetricHandler.java

License:Apache License

private void onOpenSecureChannel(ChannelHandlerContext ctx, ByteBuf buffer) throws UaException {
    buffer.skipBytes(3 + 1 + 4); // skip messageType, chunkType, messageSize

    long secureChannelId = buffer.readUnsignedInt();

    secureChannel.setChannelId(secureChannelId);

    AsymmetricSecurityHeader securityHeader = AsymmetricSecurityHeader.decode(buffer);
    if (!headerRef.compareAndSet(null, securityHeader)) {
        if (!securityHeader.equals(headerRef.get())) {
            throw new UaRuntimeException(StatusCodes.Bad_SecurityChecksFailed,
                    "subsequent AsymmetricSecurityHeader did not match");
        }/*from  ww  w.j  a  v a 2 s  .com*/
    }

    int chunkSize = buffer.readerIndex(0).readableBytes();

    if (chunkSize > maxChunkSize) {
        throw new UaException(StatusCodes.Bad_TcpMessageTooLarge,
                String.format("max chunk size exceeded (%s)", maxChunkSize));
    }

    chunkBuffers.add(buffer.retain());

    if (chunkBuffers.size() > maxChunkCount) {
        throw new UaException(StatusCodes.Bad_TcpMessageTooLarge,
                String.format("max chunk count exceeded (%s)", maxChunkCount));
    }

    char chunkType = (char) buffer.getByte(3);

    if (chunkType == 'A' || chunkType == 'F') {
        final List<ByteBuf> buffersToDecode = chunkBuffers;
        chunkBuffers = new ArrayList<>(maxChunkCount);

        serializationQueue.decode((binaryDecoder, chunkDecoder) -> {
            ByteBuf decodedBuffer = null;

            try {
                decodedBuffer = chunkDecoder.decodeAsymmetric(secureChannel, buffersToDecode);

                UaResponseMessage responseMessage = binaryDecoder.setBuffer(decodedBuffer).decodeMessage(null);

                StatusCode serviceResult = responseMessage.getResponseHeader().getServiceResult();

                if (serviceResult.isGood()) {
                    OpenSecureChannelResponse response = (OpenSecureChannelResponse) responseMessage;

                    secureChannel.setChannelId(response.getSecurityToken().getChannelId().longValue());
                    logger.debug("Received OpenSecureChannelResponse.");

                    installSecurityToken(ctx, response);
                } else {
                    ServiceFault serviceFault = (responseMessage instanceof ServiceFault)
                            ? (ServiceFault) responseMessage
                            : new ServiceFault(responseMessage.getResponseHeader());

                    throw new UaServiceFaultException(serviceFault);
                }
            } catch (MessageAbortedException e) {
                logger.error("Received message abort chunk; error={}, reason={}", e.getStatusCode(),
                        e.getMessage());
                ctx.close();
            } catch (Throwable t) {
                logger.error("Error decoding OpenSecureChannelResponse: {}", t.getMessage(), t);
                ctx.close();
            } finally {
                if (decodedBuffer != null) {
                    decodedBuffer.release();
                }
                buffersToDecode.clear();
            }
        });
    }
}

From source file:com.digitalpetri.opcua.stack.client.handlers.UaTcpClientMessageHandler.java

License:Apache License

private boolean accumulateChunk(ByteBuf buffer) throws UaException {
    int maxChunkCount = serializationQueue.getParameters().getLocalMaxChunkCount();
    int maxChunkSize = serializationQueue.getParameters().getLocalReceiveBufferSize();

    int chunkSize = buffer.readerIndex(0).readableBytes();

    if (chunkSize > maxChunkSize) {
        throw new UaException(StatusCodes.Bad_TcpMessageTooLarge,
                String.format("max chunk size exceeded (%s)", maxChunkSize));
    }//from   ww w .  ja v  a 2 s  .c  o  m

    chunkBuffers.add(buffer.retain());

    if (chunkBuffers.size() > maxChunkCount) {
        throw new UaException(StatusCodes.Bad_TcpMessageTooLarge,
                String.format("max chunk count exceeded (%s)", maxChunkCount));
    }

    char chunkType = (char) buffer.getByte(3);

    return (chunkType == 'A' || chunkType == 'F');
}

From source file:com.digitalpetri.opcua.stack.client.handlers.UaTcpClientSymmetricHandler.java

License:Apache License

private void onSecureMessage(ChannelHandlerContext ctx, ByteBuf buffer) throws UaException {
    buffer.skipBytes(3 + 1 + 4); // skip messageType, chunkType, messageSize

    long secureChannelId = buffer.readUnsignedInt();
    if (secureChannelId != secureChannel.getChannelId()) {
        throw new UaException(StatusCodes.Bad_SecureChannelIdInvalid,
                "invalid secure channel id: " + secureChannelId);
    }//w ww  . j  a v a2 s . c  o  m

    int chunkSize = buffer.readerIndex(0).readableBytes();
    if (chunkSize > maxChunkSize) {
        throw new UaException(StatusCodes.Bad_TcpMessageTooLarge,
                String.format("max chunk size exceeded (%s)", maxChunkSize));
    }

    chunkBuffers.add(buffer.retain());

    if (chunkBuffers.size() > maxChunkCount) {
        throw new UaException(StatusCodes.Bad_TcpMessageTooLarge,
                String.format("max chunk count exceeded (%s)", maxChunkCount));
    }

    char chunkType = (char) buffer.getByte(3);

    if (chunkType == 'A' || chunkType == 'F') {
        final List<ByteBuf> buffersToDecode = chunkBuffers;
        chunkBuffers = new ArrayList<>(maxChunkCount);

        serializationQueue.decode((binaryDecoder, chunkDecoder) -> {
            ByteBuf decodedBuffer = null;

            try {
                validateChunkHeaders(buffersToDecode);

                decodedBuffer = chunkDecoder.decodeSymmetric(secureChannel, buffersToDecode);

                binaryDecoder.setBuffer(decodedBuffer);
                UaResponseMessage response = binaryDecoder.decodeMessage(null);

                UaRequestFuture request = pending.remove(chunkDecoder.getLastRequestId());

                if (request != null) {
                    client.getExecutorService().execute(() -> request.getFuture().complete(response));
                } else {
                    logger.warn("No UaRequestFuture for requestId={}", chunkDecoder.getLastRequestId());
                }
            } catch (MessageAbortedException e) {
                logger.debug("Received message abort chunk; error={}, reason={}", e.getStatusCode(),
                        e.getMessage());

                UaRequestFuture request = pending.remove(chunkDecoder.getLastRequestId());

                if (request != null) {
                    client.getExecutorService().execute(() -> request.getFuture().completeExceptionally(e));
                } else {
                    logger.warn("No UaRequestFuture for requestId={}", chunkDecoder.getLastRequestId());
                }
            } catch (Throwable t) {
                logger.error("Error decoding symmetric message: {}", t.getMessage(), t);
                ctx.close();
                serializationQueue.pause();
            } finally {
                if (decodedBuffer != null) {
                    decodedBuffer.release();
                }
                buffersToDecode.clear();
            }
        });
    }
}

From source file:com.digitalpetri.opcua.stack.client.handlers.UaTcpClientSymmetricHandler.java

License:Apache License

private void validateChunkHeaders(List<ByteBuf> chunkBuffers) throws UaException {
    ChannelSecurity channelSecurity = secureChannel.getChannelSecurity();
    long currentTokenId = channelSecurity.getCurrentToken().getTokenId().longValue();
    long previousTokenId = channelSecurity.getPreviousToken().map(t -> t.getTokenId().longValue()).orElse(-1L);

    for (ByteBuf chunkBuffer : chunkBuffers) {
        chunkBuffer.skipBytes(3 + 1 + 4 + 4); // skip messageType, chunkType, messageSize, secureChannelId

        SymmetricSecurityHeader securityHeader = SymmetricSecurityHeader.decode(chunkBuffer);

        if (securityHeader.getTokenId() != currentTokenId) {
            if (securityHeader.getTokenId() != previousTokenId) {
                String message = String.format(
                        "received unknown secure channel token. "
                                + "tokenId=%s, currentTokenId=%s, previousTokenId=%s",
                        securityHeader.getTokenId(), currentTokenId, previousTokenId);

                throw new UaException(StatusCodes.Bad_SecureChannelTokenUnknown, message);
            }/*from  w  w w.ja v  a 2s . c  om*/
        }

        chunkBuffer.readerIndex(0);
    }
}

From source file:com.digitalpetri.opcua.stack.core.channel.ChunkEncoder.java

License:Apache License

private List<ByteBuf> encode(Delegate delegate, SecureChannel channel, MessageType messageType,
        ByteBuf messageBuffer, long requestId) throws UaException {

    List<ByteBuf> chunks = new ArrayList<>();

    boolean encrypted = delegate.isEncryptionEnabled(channel);

    int securityHeaderSize = delegate.getSecurityHeaderSize(channel);
    int cipherTextBlockSize = delegate.getCipherTextBlockSize(channel);
    int plainTextBlockSize = delegate.getPlainTextBlockSize(channel);
    int signatureSize = delegate.getSignatureSize(channel);

    int maxChunkSize = parameters.getLocalSendBufferSize();
    int headerSizes = SecureMessageHeader.SECURE_MESSAGE_HEADER_SIZE + securityHeaderSize;
    int paddingOverhead = encrypted ? (cipherTextBlockSize > 256 ? 2 : 1) : 0;

    int maxBlockCount = (maxChunkSize - headerSizes - signatureSize - paddingOverhead) / cipherTextBlockSize;
    int maxBodySize = (plainTextBlockSize * maxBlockCount - SequenceHeader.SEQUENCE_HEADER_SIZE);

    while (messageBuffer.readableBytes() > 0) {
        int bodySize = Math.min(messageBuffer.readableBytes(), maxBodySize);

        int paddingSize = encrypted
                ? plainTextBlockSize/* w w  w. j  ava 2 s.c o m*/
                        - (SequenceHeader.SEQUENCE_HEADER_SIZE + bodySize + signatureSize + paddingOverhead)
                                % plainTextBlockSize
                : 0;

        int plainTextContentSize = SequenceHeader.SEQUENCE_HEADER_SIZE + bodySize + signatureSize + paddingSize
                + paddingOverhead;

        assert (plainTextContentSize % plainTextBlockSize == 0);

        int chunkSize = SecureMessageHeader.SECURE_MESSAGE_HEADER_SIZE + securityHeaderSize
                + (plainTextContentSize / plainTextBlockSize) * cipherTextBlockSize;

        ByteBuf chunkBuffer = BufferUtil.buffer(chunkSize);

        /* Message Header */
        SecureMessageHeader messageHeader = new SecureMessageHeader(messageType,
                messageBuffer.readableBytes() > bodySize ? 'C' : 'F', chunkSize, channel.getChannelId());

        SecureMessageHeader.encode(messageHeader, chunkBuffer);

        /* Security Header */
        delegate.encodeSecurityHeader(channel, chunkBuffer);

        /* Sequence Header */
        SequenceHeader sequenceHeader = new SequenceHeader(sequenceNumber.getAndIncrement(), requestId);

        SequenceHeader.encode(sequenceHeader, chunkBuffer);

        /* Message Body */
        chunkBuffer.writeBytes(messageBuffer, bodySize);

        /* Padding and Signature */
        if (encrypted) {
            writePadding(cipherTextBlockSize, paddingSize, chunkBuffer);
        }

        if (delegate.isSigningEnabled(channel)) {
            ByteBuffer chunkNioBuffer = chunkBuffer.nioBuffer(0, chunkBuffer.writerIndex());

            byte[] signature = delegate.signChunk(channel, chunkNioBuffer);

            chunkBuffer.writeBytes(signature);
        }

        /* Encryption */
        if (encrypted) {
            chunkBuffer.readerIndex(SecureMessageHeader.SECURE_MESSAGE_HEADER_SIZE + securityHeaderSize);

            assert (chunkBuffer.readableBytes() % plainTextBlockSize == 0);

            try {
                int blockCount = chunkBuffer.readableBytes() / plainTextBlockSize;

                ByteBuffer chunkNioBuffer = chunkBuffer.nioBuffer(chunkBuffer.readerIndex(),
                        blockCount * cipherTextBlockSize);
                ByteBuf copyBuffer = chunkBuffer.copy();
                ByteBuffer plainTextNioBuffer = copyBuffer.nioBuffer();

                Cipher cipher = delegate.getAndInitializeCipher(channel);

                if (delegate instanceof AsymmetricDelegate) {
                    for (int blockNumber = 0; blockNumber < blockCount; blockNumber++) {
                        int position = blockNumber * plainTextBlockSize;
                        int limit = (blockNumber + 1) * plainTextBlockSize;
                        plainTextNioBuffer.position(position).limit(limit);

                        int bytesWritten = cipher.doFinal(plainTextNioBuffer, chunkNioBuffer);

                        assert (bytesWritten == cipherTextBlockSize);
                    }
                } else {
                    cipher.doFinal(plainTextNioBuffer, chunkNioBuffer);
                }

                copyBuffer.release();
            } catch (GeneralSecurityException e) {
                throw new UaException(StatusCodes.Bad_SecurityChecksFailed, e);
            }
        }

        chunkBuffer.readerIndex(0).writerIndex(chunkSize);

        chunks.add(chunkBuffer);
    }

    lastRequestId = requestId;

    return chunks;
}

From source file:com.digitalpetri.opcua.stack.server.handlers.UaTcpServerAsymmetricHandler.java

License:Apache License

private void onOpenSecureChannel(ChannelHandlerContext ctx, ByteBuf buffer) throws UaException {
    buffer.skipBytes(3); // Skip messageType

    char chunkType = (char) buffer.readByte();

    if (chunkType == 'A') {
        chunkBuffers.forEach(ByteBuf::release);
        chunkBuffers.clear();/*w  w w. j  a  v  a 2s  . com*/
        headerRef.set(null);
    } else {
        buffer.skipBytes(4); // Skip messageSize

        long secureChannelId = buffer.readUnsignedInt();
        AsymmetricSecurityHeader securityHeader = AsymmetricSecurityHeader.decode(buffer);

        if (secureChannelId == 0) {
            // Okay, this is the first OpenSecureChannelRequest... carry on.
            String endpointUrl = ctx.channel().attr(UaTcpServerHelloHandler.ENDPOINT_URL_KEY).get();
            String securityPolicyUri = securityHeader.getSecurityPolicyUri();

            EndpointDescription endpointDescription = Arrays.stream(server.getEndpointDescriptions())
                    .filter(e -> {
                        String s1 = pathOrUrl(endpointUrl);
                        String s2 = pathOrUrl(e.getEndpointUrl());
                        boolean uriMatch = s1.equals(s2);
                        boolean policyMatch = e.getSecurityPolicyUri().equals(securityPolicyUri);
                        return uriMatch && policyMatch;
                    }).findFirst().orElse(null);

            if (endpointDescription == null && !server.getConfig().isStrictEndpointUrlsEnabled()) {
                endpointDescription = Arrays.stream(server.getEndpointDescriptions())
                        .filter(e -> e.getSecurityPolicyUri().equals(securityPolicyUri)).findFirst()
                        .orElse(null);
            }

            if (endpointDescription == null) {
                throw new UaException(StatusCodes.Bad_SecurityChecksFailed, "SecurityPolicy URI did not match");
            }

            secureChannel = server.openSecureChannel();
            secureChannel.setEndpointDescription(endpointDescription);
        } else {
            secureChannel = server.getSecureChannel(secureChannelId);

            if (secureChannel == null) {
                throw new UaException(StatusCodes.Bad_TcpSecureChannelUnknown,
                        "unknown secure channel id: " + secureChannelId);
            }

            if (!secureChannel.getRemoteCertificateBytes().equals(securityHeader.getSenderCertificate())) {
                throw new UaException(StatusCodes.Bad_SecurityChecksFailed,
                        "certificate requesting renewal did not match existing certificate.");
            }

            Channel boundChannel = secureChannel.attr(UaTcpStackServer.BoundChannelKey).get();
            if (boundChannel != null && boundChannel != ctx.channel()) {
                throw new UaException(StatusCodes.Bad_SecurityChecksFailed,
                        "received a renewal request from channel other than the bound channel.");
            }
        }

        if (!headerRef.compareAndSet(null, securityHeader)) {
            if (!securityHeader.equals(headerRef.get())) {
                throw new UaException(StatusCodes.Bad_SecurityChecksFailed,
                        "subsequent AsymmetricSecurityHeader did not match");
            }
        }

        SecurityPolicy securityPolicy = SecurityPolicy.fromUri(securityHeader.getSecurityPolicyUri());
        secureChannel.setSecurityPolicy(securityPolicy);

        if (!securityHeader.getSenderCertificate().isNull() && securityPolicy != SecurityPolicy.None) {
            secureChannel.setRemoteCertificate(securityHeader.getSenderCertificate().bytes());

            try {
                CertificateValidator certificateValidator = server.getCertificateValidator();

                certificateValidator.validate(secureChannel.getRemoteCertificate());

                certificateValidator.verifyTrustChain(secureChannel.getRemoteCertificate(),
                        secureChannel.getRemoteCertificateChain());
            } catch (UaException e) {
                try {
                    UaException cause = new UaException(e.getStatusCode(), "security checks failed");
                    ErrorMessage errorMessage = ExceptionHandler.sendErrorMessage(ctx, cause);

                    logger.debug("[remote={}] {}.", ctx.channel().remoteAddress(), errorMessage.getReason(),
                            cause);
                } catch (Exception ignored) {
                }
            }
        }

        if (!securityHeader.getReceiverThumbprint().isNull()) {
            CertificateManager certificateManager = server.getCertificateManager();

            Optional<X509Certificate> localCertificate = certificateManager
                    .getCertificate(securityHeader.getReceiverThumbprint());

            Optional<KeyPair> keyPair = certificateManager.getKeyPair(securityHeader.getReceiverThumbprint());

            if (localCertificate.isPresent() && keyPair.isPresent()) {
                secureChannel.setLocalCertificate(localCertificate.get());
                secureChannel.setKeyPair(keyPair.get());
            } else {
                throw new UaException(StatusCodes.Bad_SecurityChecksFailed,
                        "no certificate for provided thumbprint");
            }
        }

        int chunkSize = buffer.readerIndex(0).readableBytes();

        if (chunkSize > maxChunkSize) {
            throw new UaException(StatusCodes.Bad_TcpMessageTooLarge,
                    String.format("max chunk size exceeded (%s)", maxChunkSize));
        }

        chunkBuffers.add(buffer.retain());

        if (chunkBuffers.size() > maxChunkCount) {
            throw new UaException(StatusCodes.Bad_TcpMessageTooLarge,
                    String.format("max chunk count exceeded (%s)", maxChunkCount));
        }

        if (chunkType == 'F') {
            final List<ByteBuf> buffersToDecode = chunkBuffers;

            chunkBuffers = new ArrayList<>(maxChunkCount);
            headerRef.set(null);

            serializationQueue.decode((binaryDecoder, chunkDecoder) -> {
                ByteBuf messageBuffer = null;

                try {
                    messageBuffer = chunkDecoder.decodeAsymmetric(secureChannel, buffersToDecode);

                    OpenSecureChannelRequest request = binaryDecoder.setBuffer(messageBuffer)
                            .decodeMessage(null);

                    logger.debug("Received OpenSecureChannelRequest ({}, id={}).", request.getRequestType(),
                            secureChannelId);

                    long requestId = chunkDecoder.getLastRequestId();
                    installSecurityToken(ctx, request, requestId);
                } catch (UaException e) {
                    logger.error("Error decoding asymmetric message: {}", e.getMessage(), e);
                    ctx.close();
                } finally {
                    if (messageBuffer != null) {
                        messageBuffer.release();
                    }
                    buffersToDecode.clear();
                }
            });
        }
    }
}

From source file:com.digitalpetri.opcua.stack.server.handlers.UaTcpServerSymmetricHandler.java

License:Apache License

private void onSecureMessage(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws UaException {
    buffer.skipBytes(3); // Skip messageType

    char chunkType = (char) buffer.readByte();

    if (chunkType == 'A') {
        chunkBuffers.forEach(ByteBuf::release);
        chunkBuffers.clear();//from www .  j  ava  2s  .co  m
    } else {
        buffer.skipBytes(4); // Skip messageSize

        long secureChannelId = buffer.readUnsignedInt();
        if (secureChannelId != secureChannel.getChannelId()) {
            throw new UaException(StatusCodes.Bad_SecureChannelIdInvalid,
                    "invalid secure channel id: " + secureChannelId);
        }

        int chunkSize = buffer.readerIndex(0).readableBytes();
        if (chunkSize > maxChunkSize) {
            throw new UaException(StatusCodes.Bad_TcpMessageTooLarge,
                    String.format("max chunk size exceeded (%s)", maxChunkSize));
        }

        chunkBuffers.add(buffer.retain());

        if (chunkBuffers.size() > maxChunkCount) {
            throw new UaException(StatusCodes.Bad_TcpMessageTooLarge,
                    String.format("max chunk count exceeded (%s)", maxChunkCount));
        }

        if (chunkType == 'F') {
            final List<ByteBuf> buffersToDecode = chunkBuffers;
            chunkBuffers = new ArrayList<>(maxChunkCount);

            serializationQueue.decode((binaryDecoder, chunkDecoder) -> {
                try {
                    validateChunkHeaders(buffersToDecode);

                    ByteBuf messageBuffer = chunkDecoder.decodeSymmetric(secureChannel, buffersToDecode);

                    binaryDecoder.setBuffer(messageBuffer);
                    UaRequestMessage request = binaryDecoder.decodeMessage(null);

                    ServiceRequest<UaRequestMessage, UaResponseMessage> serviceRequest = new ServiceRequest<>(
                            request, chunkDecoder.getLastRequestId(), server, secureChannel);

                    server.getExecutorService().execute(() -> server.receiveRequest(serviceRequest));

                    messageBuffer.release();
                    buffersToDecode.clear();
                } catch (UaException e) {
                    logger.error("Error decoding symmetric message: {}", e.getMessage(), e);
                    ctx.close();
                }
            });
        }
    }
}

From source file:com.friz.game.network.codec.LoginDecoder.java

License:Open Source License

@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buf, List<Object> out) throws Exception {
    int type = buf.readUnsignedByte();
    int size = buf.readUnsignedShort();

    int major = buf.readInt();
    int minor = buf.readInt();
    boolean dropped = buf.readBoolean();

    int rsaSize = buf.readUnsignedShort();
    byte[] rsa = new byte[rsaSize];
    buf.readBytes(rsa);//  w ww. j  a va2 s  .com

    ByteBuf rsaBuf = Unpooled.wrappedBuffer(
            new BigInteger(rsa).modPow(Constants.LOGIN_EXPONENT, Constants.LOGIN_MODULUS).toByteArray());
    int rsaMagic = rsaBuf.readUnsignedByte();

    int[] key = new int[4];
    for (int i = 0; i < key.length; i++)
        key[i] = rsaBuf.readInt();

    int block = rsaBuf.readUnsignedByte();

    if (block == 1 || block == 3) {
        int code = rsaBuf.readUnsignedMedium();
        rsaBuf.readerIndex(rsaBuf.readerIndex() + 1);
    } else if (block == 0) {
        int trusted = rsaBuf.readInt();
    } else if (block == 2) {
        rsaBuf.readerIndex(rsaBuf.readerIndex() + 4);
    }

    String password = BufferUtils.getString(rsaBuf);

    long serverKey = rsaBuf.readLong();
    long clientKey = rsaBuf.readLong();

    byte[] xtea = new byte[buf.readableBytes()];
    buf.readBytes(xtea);
    ByteBuf xteaBuf = Unpooled.wrappedBuffer(new XTEA(xtea).decrypt(key).toByteArray());

    String username = "";
    boolean asString = xteaBuf.readBoolean();
    if (asString)
        username = BufferUtils.getString(xteaBuf);
    else
        username = BufferUtils.getBase37(xteaBuf);

    int display = xteaBuf.readUnsignedByte();
    int width = xteaBuf.readUnsignedShort();
    int height = xteaBuf.readUnsignedShort();

    int multisample = xteaBuf.readByte();

    byte[] uid = new byte[24];
    for (int i = 0; i < uid.length; i++)
        uid[i] = xteaBuf.readByte();

    String token = BufferUtils.getString(xteaBuf);

    int prefSize = xteaBuf.readUnsignedByte();
    int prefVersion = xteaBuf.readUnsignedByte();
    int aPref = xteaBuf.readUnsignedByte();
    int antiAliasing = xteaBuf.readUnsignedByte();
    int aPref1 = xteaBuf.readUnsignedByte();
    int bloom = xteaBuf.readUnsignedByte();
    int brightness = xteaBuf.readUnsignedByte();
    int buildArea = xteaBuf.readUnsignedByte();
    int aPref2 = xteaBuf.readUnsignedByte();
    int flickeringEffects = xteaBuf.readUnsignedByte();
    int fog = xteaBuf.readUnsignedByte();
    int groundBlending = xteaBuf.readUnsignedByte();
    int groundDecoration = xteaBuf.readUnsignedByte();
    int idleAnimations = xteaBuf.readUnsignedByte();
    int lighting = xteaBuf.readUnsignedByte();
    int sceneryShadows = xteaBuf.readUnsignedByte();
    int aPref3 = xteaBuf.readUnsignedByte();
    int nullPref = xteaBuf.readUnsignedByte();
    int orthoMode = xteaBuf.readUnsignedByte();
    int particles = xteaBuf.readUnsignedByte();
    int removeRoofs = xteaBuf.readUnsignedByte();
    int maxScreenSize = xteaBuf.readUnsignedByte();
    int skyboxes = xteaBuf.readUnsignedByte();
    int mobShadows = xteaBuf.readUnsignedByte();
    int textures = xteaBuf.readUnsignedByte();
    int desiredToolkit = xteaBuf.readUnsignedByte();
    int nullPref1 = xteaBuf.readUnsignedByte();
    int water = xteaBuf.readUnsignedByte();
    int screenSize = xteaBuf.readUnsignedByte();
    int customCursors = xteaBuf.readUnsignedByte();
    int graphics = xteaBuf.readUnsignedByte();
    int cpu = xteaBuf.readUnsignedByte();
    int aPref4 = xteaBuf.readUnsignedByte();
    int safeMode = xteaBuf.readUnsignedByte();
    int aPref5 = xteaBuf.readUnsignedByte();
    int aPref6 = xteaBuf.readUnsignedByte();
    int aPref7 = xteaBuf.readUnsignedByte();
    int soundEffectsVolume = xteaBuf.readUnsignedByte();
    int areaSoundsVolume = xteaBuf.readUnsignedByte();
    int voiceOverVolume = xteaBuf.readUnsignedByte();
    int musicVolume = xteaBuf.readUnsignedByte();
    int themeMusicVolume = xteaBuf.readUnsignedByte();
    int steroSound = xteaBuf.readUnsignedByte();

    int infoVersion = xteaBuf.readUnsignedByte();
    int osType = xteaBuf.readUnsignedByte();
    boolean arch64 = xteaBuf.readBoolean();
    int versionType = xteaBuf.readUnsignedByte();
    int vendorType = xteaBuf.readUnsignedByte();
    int jMajor = xteaBuf.readUnsignedByte();
    int jMinor = xteaBuf.readUnsignedByte();
    int jPatch = xteaBuf.readUnsignedByte();
    boolean falseBool = xteaBuf.readBoolean();
    int heapSize = xteaBuf.readUnsignedShort();
    int pocessorCount = xteaBuf.readUnsignedByte();
    int cpuPhyscialMemory = xteaBuf.readUnsignedMedium();
    int cpuClock = xteaBuf.readUnsignedShort();
    String gpuName = BufferUtils.getJagString(xteaBuf);
    String aString = BufferUtils.getJagString(xteaBuf);
    String dxVersion = BufferUtils.getJagString(xteaBuf);
    String aString1 = BufferUtils.getJagString(xteaBuf);
    int gpuDriverMonth = xteaBuf.readUnsignedByte();
    int gpuDriverYear = xteaBuf.readUnsignedShort();
    String cpuType = BufferUtils.getJagString(xteaBuf);
    String cpuName = BufferUtils.getJagString(xteaBuf);
    int cpuThreads = xteaBuf.readUnsignedByte();
    int anInt = xteaBuf.readUnsignedByte();
    int anInt1 = xteaBuf.readInt();
    int anInt2 = xteaBuf.readInt();
    int anInt3 = xteaBuf.readInt();
    int anInt4 = xteaBuf.readInt();
    String aString2 = BufferUtils.getString(xteaBuf);

    int anInt5 = xteaBuf.readInt();
    int anInt6 = xteaBuf.readInt();
    int anInt7 = xteaBuf.readInt();
    String aString3 = BufferUtils.getString(xteaBuf);

    boolean hasAdditional = xteaBuf.readBoolean();
    String additionalInfo = "";
    if (hasAdditional)
        additionalInfo = BufferUtils.getString(xteaBuf);

    int anInt8 = xteaBuf.readUnsignedByte();
    int anInt9 = xteaBuf.readUnsignedByte();
    int anInt10 = xteaBuf.readUnsignedByte();
    int anInt11 = xteaBuf.readInt();
    String aString4 = BufferUtils.getString(xteaBuf);

    boolean newWorld = xteaBuf.readBoolean();
    int lobbyId = xteaBuf.readUnsignedShort();

    int[] checksums = new int[(xteaBuf.readableBytes() / 4) + 1];
    for (int i = 0; i < checksums.length; i++) {
        if (i == 32)
            checksums[i] = -1;
        else
            checksums[i] = xteaBuf.readInt();
    }
}