Example usage for io.netty.buffer ByteBuf release

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

Introduction

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

Prototype

boolean release();

Source Link

Document

Decreases the reference count by 1 and deallocates this object if the reference count reaches at 0 .

Usage

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//from  w  w  w .  j a  va  2s .  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.core.serialization.OpcUaDataTypeEncoding.java

License:Apache License

@Override
public ByteString encodeToByteString(Object object, NodeId encodingTypeId) {
    EncoderDelegate<Object> delegate = DelegateRegistry.getEncoder(encodingTypeId);

    ByteBuf buffer = allocator.buffer().order(ByteOrder.LITTLE_ENDIAN);

    BinaryEncoder encoder = new BinaryEncoder();
    encoder.setBuffer(buffer);//  w w w  .ja va  2s  .c  om

    delegate.encode(object, encoder);

    byte[] bs = new byte[buffer.readableBytes()];
    buffer.readBytes(bs);
    buffer.release();

    return ByteString.of(bs);
}

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();//from   w w  w  .j  a  va 2 s .  c  om
        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.UaTcpServerAsymmetricHandler.java

License:Apache License

private void sendOpenSecureChannelResponse(ChannelHandlerContext ctx, long requestId,
        OpenSecureChannelResponse response) {
    serializationQueue.encode((binaryEncoder, chunkEncoder) -> {
        ByteBuf messageBuffer = BufferUtil.buffer();

        try {//from  w  ww  .  j a  v a  2 s  . co m
            binaryEncoder.setBuffer(messageBuffer);
            binaryEncoder.encodeMessage(null, response);

            List<ByteBuf> chunks = chunkEncoder.encodeAsymmetric(secureChannel, MessageType.OpenSecureChannel,
                    messageBuffer, requestId);

            if (!symmetricHandlerAdded) {
                ctx.pipeline()
                        .addFirst(new UaTcpServerSymmetricHandler(server, serializationQueue, secureChannel));
                symmetricHandlerAdded = true;
            }

            chunks.forEach(c -> ctx.write(c, ctx.voidPromise()));
            ctx.flush();

            long lifetime = response.getSecurityToken().getRevisedLifetime().longValue();
            server.secureChannelIssuedOrRenewed(secureChannel, lifetime);

            logger.debug("Sent OpenSecureChannelResponse.");
        } catch (UaException e) {
            logger.error("Error encoding OpenSecureChannelResponse: {}", e.getMessage(), e);
            ctx.close();
        } finally {
            messageBuffer.release();
        }
    });
}

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

License:Apache License

@Override
protected void encode(ChannelHandlerContext ctx, ServiceResponse message, ByteBuf out) throws Exception {
    serializationQueue.encode((binaryEncoder, chunkEncoder) -> {
        ByteBuf messageBuffer = BufferUtil.buffer();

        try {/*from   w ww.  j a  va2s  .  c o  m*/
            binaryEncoder.setBuffer(messageBuffer);
            binaryEncoder.encodeMessage(null, message.getResponse());

            final List<ByteBuf> chunks = chunkEncoder.encodeSymmetric(secureChannel, MessageType.SecureMessage,
                    messageBuffer, message.getRequestId());

            ctx.executor().execute(() -> {
                chunks.forEach(c -> ctx.write(c, ctx.voidPromise()));
                ctx.flush();
            });
        } catch (UaException e) {
            logger.error("Error encoding {}: {}", message.getResponse().getClass(), e.getMessage(), e);
            ctx.close();
        } finally {
            messageBuffer.release();
        }
    });
}

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 ww w . ja  v  a 2 s  .c  om
    } 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.diwayou.hybrid.remoting.netty.NettyDecoder.java

License:Apache License

@Override
public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
    ByteBuf frame = null;
    try {//from   w  w  w  . ja  v a  2  s. c o  m
        frame = (ByteBuf) super.decode(ctx, in);
        if (null == frame) {
            return null;
        }

        ByteBuffer byteBuffer = frame.nioBuffer();

        return RemotingCommand.decode(byteBuffer);
    } catch (Exception e) {
        log.error("decode exception, " + RemotingHelper.parseChannelRemoteAddr(ctx.channel()), e);
        // ? pipelineclose???
        RemotingUtil.closeChannel(ctx.channel());
    } finally {
        if (null != frame) {
            frame.release();
        }
    }

    return null;
}

From source file:com.easy.remoting.netty.handler.EasyDecoder.java

License:Apache License

@Override
public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
    ByteBuf frame = null;
    try {/*w ww  .j  a va  2 s. c o m*/
        frame = (ByteBuf) super.decode(ctx, in);
        if (null == frame) {
            return null;
        }

        ByteBuffer byteBuffer = frame.nioBuffer();

        return Cmd.decode(byteBuffer);
    } catch (Exception e) {
        log.error("decode exception:{}", e);

        ctx.channel().close().addListener(ChannelFutureListener.CLOSE);

    } finally {
        if (null != frame) {
            frame.release();
        }
    }

    return null;
}

From source file:com.ebay.jetstream.messaging.transport.netty.compression.MessageCompressionHandler.java

License:MIT License

/**
 * Invoked when {@link Channel#write(Object)} is called.
 *///from   ww w .  ja  va 2s.  c o  m
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {

    try {

        Attribute<Boolean> attr = ctx.channel().attr(EventProducer.m_eckey);

        Boolean enableCompression = attr.get();

        if ((enableCompression != null) && (enableCompression == true)) {

            ByteBuf chbuf = (ByteBuf) msg;

            int msglen = chbuf.readableBytes();
            ExtendedChannelPromise epromise = (ExtendedChannelPromise) promise;
            epromise.setRawBytes(msglen);

            byte[] compressed = Snappy.rawCompress(chbuf.readBytes(msglen).array(), msglen);

            epromise.setCompressedBytes(compressed.length + 4);
            chbuf.release(); // need to release the original buffer - do I need to check if this this a ref counted buffer

            ByteBuf sendbuf = ctx.alloc().buffer();

            sendbuf.writeInt(compressed.length);
            sendbuf.writeBytes(compressed);

            ctx.write(sendbuf, promise);

            m_totalMessagesCompressed.increment();

        } else {

            ctx.write(msg, promise);

        }

    } catch (Throwable t) {
        m_totalMessagesDropped.increment();
        LOGGER.debug("Failed to compress message - " + t.getLocalizedMessage());

    }

}

From source file:com.ebay.jetstream.messaging.transport.netty.compression.MessageDecompressionHandler.java

License:MIT License

@Override
protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {

    ByteBuf frame = (ByteBuf) super.decode(ctx, in);

    if (frame == null) {
        return null;
    }// w  w w.ja v a 2 s  . c o m

    byte[] uncompressedbuf;

    if (m_allocBuf)
        uncompressedbuf = new byte[m_tmpBufSz];
    else
        uncompressedbuf = m_tmpBuf;

    int framelen = frame.readableBytes();

    int len = 0;

    try {

        len = Snappy.rawUncompress(frame.readBytes(framelen).array(), 0, framelen, uncompressedbuf, 0);

    } catch (Throwable t) {

        LOGGER.debug("Failed to uncompress - " + t.getLocalizedMessage());

        frame.release();
        return null;
    }

    frame.release();

    ByteBuf buf = ctx.alloc().directBuffer(len);

    return buf.writeBytes(uncompressedbuf, 0, len);

}