List of usage examples for io.netty.buffer ByteBuf skipBytes
public abstract ByteBuf skipBytes(int length);
From source file:org.asterisque.netty.MessageDecoder.java
License:Apache License
public void decode(ChannelHandlerContext ctx, ByteBuf b, List<Object> out) throws CodecException { ByteBuffer buffer = b.nioBuffer(); Optional<Message> msg = codec.decode(buffer); if (msg.isPresent()) { b.skipBytes(buffer.position()); out.add(msg.get());/* ww w. j a v a 2s.com*/ } }
From source file:org.code_house.ebus.netty.codec.MasterTelegramDecoder.java
License:Apache License
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { if (in.readableBytes() == 0) { return;// w w w . jav a2s.c o m } // buffer we receive might be a correct frame or just data we have between frames int index = in.readerIndex(); if (in.readableBytes() >= 6) { // seven bytes is shortest valid ebus telegram, which no data byte source = in.readByte(); byte destination = in.readByte(); boolean fromMaster = Predicates.IS_MASTER.apply(source); boolean broadcast = Constants.BROADCAST_ADDRESS == destination; boolean toSlave = Predicates.IS_SLAVE.apply(destination); boolean toMaster = Predicates.IS_MASTER.apply(destination); // if below condition is correct then we have regular frame, at least it looks like, as long as we are not sure // if everything is fine we do not read but just scan buffer if (fromMaster && (toMaster || (toSlave || broadcast))) { // short is encoded on two bytes byte commandGroup = in.readByte(); byte command = in.readByte(); byte length = in.readByte(); if (in.readableBytes() >= length + 1 /* crc */) { ByteBuffer exchange = ByteBuffer.allocate(length); in.getBytes(in.readerIndex(), exchange); in.skipBytes(length); byte crc = in.readByte(); MasterData data = new MasterData(exchange, calculateCrc((byte) source, (byte) destination, commandGroup, command, length), crc); // below condition checks crc and verify if we fully consumed frame data and we will leave no remaining // bytes master buffer. If there is any data left or crc doesn't match we might just parse middle of long // telegram which accidentally got spliced or we missed for some reason SYN and just got corrupted // data. if (data.isValid()) { out.add(new MasterHeader(source, destination, commandGroup, command, length)); out.add(data); if (in.readableBytes() > 0) { out.add(in.readBytes(super.actualReadableBytes())); } return; } } } // invalid data found in.readerIndex(index); out.add(in.readBytes(super.actualReadableBytes())); } }
From source file:org.code_house.ebus.netty.codec.SlaveTelegramDecoder.java
License:Apache License
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { if (in.readableBytes() == 0) { return;/*from w ww . j a v a 2s . com*/ } int index = in.readerIndex(); // no master, no slave, no broadcast -> slave reply or ACK if (in.readableBytes() >= 3) { // we have at least three bytes which should be slave ACK, slave reply len, slave crc. byte ack = in.readByte(); if (ack == Constants.ACK) { // slave confirmed received data byte length = in.readByte(); if (in.readableBytes() >= length + 1 /* crc */) { ByteBuffer exchange = ByteBuffer.allocate(length); in.getBytes(in.readerIndex(), exchange); in.skipBytes(length); byte crc = in.readByte(); SlaveData data = new SlaveData(exchange, calculateCrc(length), crc); if (data.isValid()) { // proper slave reply out.add(new Confirmation()); out.add(new SlaveHeader(length)); out.add(data); } else { System.out.println("Slave CRC fail!!!"); in.discardReadBytes(); } } } else if (ack == Constants.NACK) { out.add(new Rejection()); } } if (out.isEmpty()) { System.out.println("slave fail -> \n" + ByteBufUtil.prettyHexDump(in)); in.readerIndex(index); } if (in.readableBytes() > 0) { out.add(in.readBytes(super.actualReadableBytes())); } }
From source file:org.eclipse.milo.opcua.stack.client.handlers.UaTcpClientAcknowledgeHandler.java
License:Open Source License
private void onAcknowledge(ChannelHandlerContext ctx, ByteBuf buffer) { if (helloTimeout != null && !helloTimeout.cancel()) { helloTimeout = null;/*w w w .j a v a2s .c om*/ handshakeFuture.completeExceptionally( new UaException(StatusCodes.Bad_Timeout, "timed out waiting for acknowledge")); ctx.close(); return; } logger.debug("Received Acknowledge message on channel={}.", ctx.channel()); buffer.skipBytes(3 + 1 + 4); // Skip messageType, chunkType, and messageSize AcknowledgeMessage acknowledge = AcknowledgeMessage.decode(buffer); long remoteProtocolVersion = acknowledge.getProtocolVersion(); long remoteReceiveBufferSize = acknowledge.getReceiveBufferSize(); long remoteSendBufferSize = acknowledge.getSendBufferSize(); long remoteMaxMessageSize = acknowledge.getMaxMessageSize(); long remoteMaxChunkCount = acknowledge.getMaxChunkCount(); if (PROTOCOL_VERSION > remoteProtocolVersion) { logger.warn("Client protocol version ({}) does not match server protocol version ({}).", PROTOCOL_VERSION, remoteProtocolVersion); } ChannelConfig config = client.getChannelConfig(); /* Our receive buffer size is determined by the remote send buffer size. */ long localReceiveBufferSize = Math.min(remoteSendBufferSize, config.getMaxChunkSize()); /* Our send buffer size is determined by the remote receive buffer size. */ long localSendBufferSize = Math.min(remoteReceiveBufferSize, config.getMaxChunkSize()); /* Max message size the remote can send us; not influenced by remote configuration. */ long localMaxMessageSize = config.getMaxMessageSize(); /* Max chunk count the remote can send us; not influenced by remote configuration. */ long localMaxChunkCount = config.getMaxChunkCount(); ChannelParameters parameters = new ChannelParameters(Ints.saturatedCast(localMaxMessageSize), Ints.saturatedCast(localReceiveBufferSize), Ints.saturatedCast(localSendBufferSize), Ints.saturatedCast(localMaxChunkCount), Ints.saturatedCast(remoteMaxMessageSize), Ints.saturatedCast(remoteReceiveBufferSize), Ints.saturatedCast(remoteSendBufferSize), Ints.saturatedCast(remoteMaxChunkCount)); ctx.channel().attr(KEY_AWAITING_HANDSHAKE).set(awaitingHandshake); ctx.executor().execute(() -> { int maxArrayLength = client.getChannelConfig().getMaxArrayLength(); int maxStringLength = client.getChannelConfig().getMaxStringLength(); SerializationQueue serializationQueue = new SerializationQueue(client.getConfig().getExecutor(), parameters, maxArrayLength, maxStringLength); UaTcpClientMessageHandler handler = new UaTcpClientMessageHandler(client, secureChannel, serializationQueue, handshakeFuture); ctx.pipeline().addLast(handler); }); }
From source file:org.eclipse.milo.opcua.stack.client.transport.uasc.UascClientAcknowledgeHandler.java
License:Open Source License
private void onAcknowledge(ChannelHandlerContext ctx, ByteBuf buffer) { if (helloTimeout != null && !helloTimeout.cancel()) { helloTimeout = null;//from w ww .j a v a 2 s .c o m handshakeFuture.completeExceptionally( new UaException(StatusCodes.Bad_Timeout, "timed out waiting for acknowledge")); ctx.close(); return; } logger.debug("Received Acknowledge message on channel={}.", ctx.channel()); buffer.skipBytes(3 + 1 + 4); // Skip messageType, chunkType, and messageSize AcknowledgeMessage acknowledge = AcknowledgeMessage.decode(buffer); long remoteProtocolVersion = acknowledge.getProtocolVersion(); long remoteReceiveBufferSize = acknowledge.getReceiveBufferSize(); long remoteSendBufferSize = acknowledge.getSendBufferSize(); long remoteMaxMessageSize = acknowledge.getMaxMessageSize(); long remoteMaxChunkCount = acknowledge.getMaxChunkCount(); if (PROTOCOL_VERSION > remoteProtocolVersion) { logger.warn("Client protocol version ({}) does not match server protocol version ({}).", PROTOCOL_VERSION, remoteProtocolVersion); } MessageLimits messageLimits = config.getMessageLimits(); /* Our receive buffer size is determined by the remote send buffer size. */ long localReceiveBufferSize = Math.min(remoteSendBufferSize, messageLimits.getMaxChunkSize()); /* Our send buffer size is determined by the remote receive buffer size. */ long localSendBufferSize = Math.min(remoteReceiveBufferSize, messageLimits.getMaxChunkSize()); /* Max message size the remote can send us; not influenced by remote configuration. */ long localMaxMessageSize = messageLimits.getMaxMessageSize(); /* Max chunk count the remote can send us; not influenced by remote configuration. */ long localMaxChunkCount = messageLimits.getMaxChunkCount(); ChannelParameters parameters = new ChannelParameters(Ints.saturatedCast(localMaxMessageSize), Ints.saturatedCast(localReceiveBufferSize), Ints.saturatedCast(localSendBufferSize), Ints.saturatedCast(localMaxChunkCount), Ints.saturatedCast(remoteMaxMessageSize), Ints.saturatedCast(remoteReceiveBufferSize), Ints.saturatedCast(remoteSendBufferSize), Ints.saturatedCast(remoteMaxChunkCount)); ctx.channel().attr(KEY_AWAITING_HANDSHAKE).set(awaitingHandshake); ctx.executor().execute(() -> { SerializationQueue serializationQueue = new SerializationQueue(config.getExecutor(), parameters, config.getEncodingLimits()); UascClientMessageHandler handler = new UascClientMessageHandler(config, secureChannel, serializationQueue, handshakeFuture); ctx.pipeline().addLast(handler); }); }
From source file:org.eclipse.milo.opcua.stack.client.transport.uasc.UascClientMessageHandler.java
License:Open Source License
private void onOpenSecureChannel(ChannelHandlerContext ctx, ByteBuf buffer) throws UaException { if (secureChannelTimeout != null) { if (secureChannelTimeout.cancel()) { logger.debug("OpenSecureChannel timeout canceled"); secureChannelTimeout = null; } else {//w w w . j a va 2 s .c o m logger.warn("timed out waiting for secure channel"); handshakeFuture.completeExceptionally( new UaException(StatusCodes.Bad_Timeout, "timed out waiting for secure channel")); ctx.close(); return; } } buffer.skipBytes(3 + 1 + 4 + 4); // skip messageType, chunkType, messageSize, secureChannelId AsymmetricSecurityHeader securityHeader = AsymmetricSecurityHeader.decode(buffer, config.getEncodingLimits().getMaxArrayLength(), config.getEncodingLimits().getMaxStringLength()); if (headerRef.compareAndSet(null, securityHeader)) { // first time we've received the header; validate and verify the server certificate CertificateValidator certificateValidator = config.getCertificateValidator(); SecurityPolicy securityPolicy = SecurityPolicy.fromUri(securityHeader.getSecurityPolicyUri()); if (securityPolicy != SecurityPolicy.None) { ByteString serverCertificateBytes = securityHeader.getSenderCertificate(); List<X509Certificate> serverCertificateChain = CertificateUtil .decodeCertificates(serverCertificateBytes.bytesOrEmpty()); certificateValidator.validate(serverCertificateChain.get(0)); certificateValidator.verifyTrustChain(serverCertificateChain); } } else { if (!securityHeader.equals(headerRef.get())) { throw new UaException(StatusCodes.Bad_SecurityChecksFailed, "subsequent AsymmetricSecurityHeader did not match"); } } if (accumulateChunk(buffer)) { final List<ByteBuf> buffersToDecode = chunkBuffers; chunkBuffers = new ArrayList<>(maxChunkCount); serializationQueue.decode((binaryDecoder, chunkDecoder) -> chunkDecoder.decodeAsymmetric(secureChannel, buffersToDecode, new ChunkDecoder.Callback() { @Override public void onDecodingError(UaException ex) { logger.error("Error decoding asymmetric message: {}", ex.getMessage(), ex); handshakeFuture.completeExceptionally(ex); ctx.close(); } @Override public void onMessageAborted(MessageAbortedException ex) { logger.warn("Asymmetric message aborted. error={} reason={}", ex.getStatusCode(), ex.getMessage()); } @Override public void onMessageDecoded(ByteBuf message, long requestId) { try { UaResponseMessage response = (UaResponseMessage) binaryDecoder.setBuffer(message) .readMessage(null); StatusCode serviceResult = response.getResponseHeader().getServiceResult(); if (serviceResult.isGood()) { OpenSecureChannelResponse oscr = (OpenSecureChannelResponse) response; secureChannel.setChannelId(oscr.getSecurityToken().getChannelId().longValue()); logger.debug("Received OpenSecureChannelResponse."); installSecurityToken(ctx, oscr); handshakeFuture.complete(secureChannel); } else { ServiceFault serviceFault = (response instanceof ServiceFault) ? (ServiceFault) response : new ServiceFault(response.getResponseHeader()); handshakeFuture .completeExceptionally(new UaServiceFaultException(serviceFault)); ctx.close(); } } catch (Throwable t) { logger.error("Error decoding OpenSecureChannelResponse", t); handshakeFuture.completeExceptionally(t); ctx.close(); } finally { message.release(); } } })); } }
From source file:org.eclipse.milo.opcua.stack.client.transport.uasc.UascClientMessageHandler.java
License:Open Source License
private void onSecureMessage(ChannelHandlerContext ctx, ByteBuf buffer) throws UaException { buffer.skipBytes(3 + 1 + 4); // skip messageType, chunkType, messageSize long secureChannelId = buffer.readUnsignedIntLE(); if (secureChannelId != secureChannel.getChannelId()) { throw new UaException(StatusCodes.Bad_SecureChannelIdInvalid, "invalid secure channel id: " + secureChannelId); }//from w w w. j a v a2 s .co m if (accumulateChunk(buffer)) { final List<ByteBuf> buffersToDecode = chunkBuffers; chunkBuffers = new ArrayList<>(maxChunkCount); serializationQueue.decode((binaryDecoder, chunkDecoder) -> { try { validateChunkHeaders(buffersToDecode); } catch (UaException e) { logger.error("Error validating chunk headers: {}", e.getMessage(), e); buffersToDecode.forEach(ReferenceCountUtil::safeRelease); ctx.close(); return; } chunkDecoder.decodeSymmetric(secureChannel, buffersToDecode, new ChunkDecoder.Callback() { @Override public void onDecodingError(UaException ex) { logger.error("Error decoding symmetric message: {}", ex.getMessage(), ex); ctx.close(); } @Override public void onMessageAborted(MessageAbortedException ex) { logger.warn("Received message abort chunk; error={}, reason={}", ex.getStatusCode(), ex.getMessage()); long requestId = ex.getRequestId(); UaTransportRequest request = pending.remove(requestId); if (request != null) { request.getFuture().completeExceptionally(ex); } else { logger.warn("No pending request for requestId={}", requestId); } } @Override public void onMessageDecoded(ByteBuf message, long requestId) { UaTransportRequest request = pending.remove(requestId); try { if (request != null) { UaResponseMessage response = (UaResponseMessage) binaryDecoder.setBuffer(message) .readMessage(null); request.getFuture().complete(response); } else { logger.warn("No pending request for requestId={}", requestId); } } catch (Throwable t) { logger.error("Error decoding UaResponseMessage", t); if (request != null) { request.getFuture().completeExceptionally(t); } } finally { message.release(); } } }); }); } }
From source file:org.eclipse.milo.opcua.stack.server.handlers.UaTcpServerAsymmetricHandler.java
License:Open Source 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();/* www .j ava 2s . 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 inner) { logger.error("Error sending ErrorMessage: {}", inner.getMessage(), inner); } } } 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:org.eclipse.milo.opcua.stack.server.transport.uasc.UascServerAsymmetricHandler.java
License:Open Source License
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception { while (buffer.readableBytes() >= HEADER_LENGTH) { int messageLength = getMessageLength(buffer, maxChunkSize); if (buffer.readableBytes() < messageLength) { break; }//from w w w. j av a 2 s . com MessageType messageType = MessageType.fromMediumInt(buffer.getMediumLE(buffer.readerIndex())); switch (messageType) { case OpenSecureChannel: onOpenSecureChannel(ctx, buffer.readSlice(messageLength)); break; case CloseSecureChannel: logger.debug("Received CloseSecureChannelRequest"); buffer.skipBytes(messageLength); if (secureChannelTimeout != null) { secureChannelTimeout.cancel(); secureChannelTimeout = null; } ctx.close(); break; default: throw new UaException(StatusCodes.Bad_TcpMessageTypeInvalid, "unexpected MessageType: " + messageType); } } }
From source file:org.eclipse.milo.opcua.stack.server.transport.uasc.UascServerAsymmetricHandler.java
License:Open Source 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 2 s . c o m*/ headerRef.set(null); } else { buffer.skipBytes(4); // Skip messageSize final long secureChannelId = buffer.readUnsignedIntLE(); final AsymmetricSecurityHeader header = AsymmetricSecurityHeader.decode(buffer, maxArrayLength, maxStringLength); if (!headerRef.compareAndSet(null, header)) { if (!header.equals(headerRef.get())) { throw new UaException(StatusCodes.Bad_SecurityChecksFailed, "subsequent AsymmetricSecurityHeader did not match"); } } if (secureChannelId != 0) { if (secureChannel == null) { throw new UaException(StatusCodes.Bad_TcpSecureChannelUnknown, "unknown secure channel id: " + secureChannelId); } if (secureChannelId != secureChannel.getChannelId()) { throw new UaException(StatusCodes.Bad_TcpSecureChannelUnknown, "unknown secure channel id: " + secureChannelId); } } if (secureChannel == null) { secureChannel = new ServerSecureChannel(); secureChannel.setChannelId(stackServer.getNextChannelId()); String securityPolicyUri = header.getSecurityPolicyUri(); SecurityPolicy securityPolicy = SecurityPolicy.fromUri(securityPolicyUri); secureChannel.setSecurityPolicy(securityPolicy); if (securityPolicy != SecurityPolicy.None) { secureChannel.setRemoteCertificate(header.getSenderCertificate().bytesOrEmpty()); CertificateValidator certificateValidator = stackServer.getConfig().getCertificateValidator(); certificateValidator.validate(secureChannel.getRemoteCertificate()); certificateValidator.verifyTrustChain(secureChannel.getRemoteCertificateChain()); CertificateManager certificateManager = stackServer.getConfig().getCertificateManager(); Optional<X509Certificate[]> localCertificateChain = certificateManager .getCertificateChain(header.getReceiverThumbprint()); Optional<KeyPair> keyPair = certificateManager.getKeyPair(header.getReceiverThumbprint()); if (localCertificateChain.isPresent() && keyPair.isPresent()) { X509Certificate[] chain = localCertificateChain.get(); secureChannel.setLocalCertificate(chain[0]); secureChannel.setLocalCertificateChain(chain); 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 (maxChunkCount > 0 && 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<>(); headerRef.set(null); serializationQueue.decode((binaryDecoder, chunkDecoder) -> chunkDecoder .decodeAsymmetric(secureChannel, buffersToDecode, new ChunkDecoder.Callback() { @Override public void onDecodingError(UaException ex) { logger.error("Error decoding asymmetric message: {}", ex.getMessage(), ex); ctx.close(); } @Override public void onMessageAborted(MessageAbortedException ex) { logger.warn("Asymmetric message aborted. error={} reason={}", ex.getStatusCode(), ex.getMessage()); } @Override public void onMessageDecoded(ByteBuf message, long requestId) { try { OpenSecureChannelRequest request = (OpenSecureChannelRequest) binaryDecoder .setBuffer(message).readMessage(null); logger.debug("Received OpenSecureChannelRequest ({}, id={}).", request.getRequestType(), secureChannelId); sendOpenSecureChannelResponse(ctx, requestId, request); } catch (Throwable t) { logger.error("Error decoding OpenSecureChannelRequest", t); ctx.close(); } finally { message.release(); buffersToDecode.clear(); } } })); } } }