use of org.eclipse.milo.opcua.stack.core.UaSerializationException in project milo by eclipse.
the class UascServerSymmetricHandler method sendServiceResponse.
private void sendServiceResponse(ChannelHandlerContext ctx, long requestId, UaRequestMessage request, UaResponseMessage response) {
serializationQueue.encode((binaryEncoder, chunkEncoder) -> {
ByteBuf messageBuffer = BufferUtil.pooledBuffer();
try {
binaryEncoder.setBuffer(messageBuffer);
binaryEncoder.writeMessage(null, response);
checkMessageSize(messageBuffer);
EncodedMessage encodedMessage = chunkEncoder.encodeSymmetric(secureChannel, requestId, messageBuffer, MessageType.SecureMessage);
CompositeByteBuf chunkComposite = BufferUtil.compositeBuffer();
for (ByteBuf chunk : encodedMessage.getMessageChunks()) {
chunkComposite.addComponent(chunk);
chunkComposite.writerIndex(chunkComposite.writerIndex() + chunk.readableBytes());
}
ctx.writeAndFlush(chunkComposite, ctx.voidPromise());
} catch (MessageEncodeException e) {
logger.error("Error encoding {}: {}", response, e.getMessage(), e);
UInteger requestHandle = request.getRequestHeader().getRequestHandle();
sendServiceFault(ctx, requestId, requestHandle, e);
} catch (UaSerializationException e) {
logger.error("Error serializing response: {}", e.getStatusCode(), e);
UInteger requestHandle = request.getRequestHeader().getRequestHandle();
sendServiceFault(ctx, requestId, requestHandle, e);
} finally {
messageBuffer.release();
}
});
}
use of org.eclipse.milo.opcua.stack.core.UaSerializationException in project milo by eclipse.
the class UascServerSymmetricHandler method checkMessageSize.
private void checkMessageSize(ByteBuf messageBuffer) throws UaSerializationException {
int messageSize = messageBuffer.readableBytes();
int remoteMaxMessageSize = serializationQueue.getParameters().getRemoteMaxMessageSize();
if (remoteMaxMessageSize > 0 && messageSize > remoteMaxMessageSize) {
throw new UaSerializationException(StatusCodes.Bad_ResponseTooLarge, "response exceeds remote max message size: " + messageSize + " > " + remoteMaxMessageSize);
}
}
use of org.eclipse.milo.opcua.stack.core.UaSerializationException in project milo by eclipse.
the class UascServerSymmetricHandler method sendServiceFault.
private void sendServiceFault(ChannelHandlerContext ctx, long requestId, UInteger requestHandle, Throwable fault) {
StatusCode statusCode = UaException.extract(fault).map(UaException::getStatusCode).orElse(StatusCode.BAD);
ServiceFault serviceFault = new ServiceFault(new ResponseHeader(DateTime.now(), requestHandle, statusCode, null, null, null));
serializationQueue.encode((binaryEncoder, chunkEncoder) -> {
ByteBuf messageBuffer = BufferUtil.pooledBuffer();
try {
binaryEncoder.setBuffer(messageBuffer);
binaryEncoder.writeMessage(null, serviceFault);
checkMessageSize(messageBuffer);
EncodedMessage encodedMessage = chunkEncoder.encodeSymmetric(secureChannel, requestId, messageBuffer, MessageType.SecureMessage);
CompositeByteBuf chunkComposite = BufferUtil.compositeBuffer();
for (ByteBuf chunk : encodedMessage.getMessageChunks()) {
chunkComposite.addComponent(chunk);
chunkComposite.writerIndex(chunkComposite.writerIndex() + chunk.readableBytes());
}
ctx.writeAndFlush(chunkComposite, ctx.voidPromise());
} catch (MessageEncodeException e) {
logger.error("Error encoding {}: {}", serviceFault, e.getMessage(), e);
} catch (UaSerializationException e) {
logger.error("Error serializing ServiceFault: {}", e.getStatusCode(), e);
} finally {
messageBuffer.release();
}
});
}
use of org.eclipse.milo.opcua.stack.core.UaSerializationException in project milo by eclipse.
the class UascServerSymmetricHandler method onSecureMessage.
private void onSecureMessage(ChannelHandlerContext ctx, ByteBuf buffer) throws UaException {
// Skip messageType
buffer.skipBytes(3);
char chunkType = (char) buffer.readByte();
if (chunkType == 'A') {
chunkBuffers.forEach(ByteBuf::release);
chunkBuffers.clear();
} else {
// Skip messageSize
buffer.skipBytes(4);
long secureChannelId = buffer.readUnsignedIntLE();
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 (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<>();
serializationQueue.decode((binaryDecoder, chunkDecoder) -> {
ByteBuf message;
long requestId;
try {
ChunkDecoder.DecodedMessage decodedMessage = chunkDecoder.decodeSymmetric(secureChannel, buffersToDecode);
message = decodedMessage.getMessage();
requestId = decodedMessage.getRequestId();
} catch (MessageAbortException e) {
logger.warn("Received message abort chunk; error={}, reason={}", e.getStatusCode(), e.getMessage());
return;
} catch (MessageDecodeException e) {
logger.error("Error decoding symmetric message", e);
ctx.close();
return;
}
try {
UaRequestMessage request = (UaRequestMessage) binaryDecoder.setBuffer(message).readMessage(null);
String endpointUrl = ctx.channel().attr(UascServerHelloHandler.ENDPOINT_URL_KEY).get();
EndpointDescription endpoint = ctx.channel().attr(UascServerAsymmetricHandler.ENDPOINT_KEY).get();
String path = EndpointUtil.getPath(endpointUrl);
InetSocketAddress remoteSocketAddress = (InetSocketAddress) ctx.channel().remoteAddress();
ServiceRequest serviceRequest = new ServiceRequest(stackServer, request, endpoint, secureChannel.getChannelId(), remoteSocketAddress.getAddress(), secureChannel.getRemoteCertificateBytes());
serviceRequest.getFuture().whenComplete((response, fault) -> {
if (response != null) {
sendServiceResponse(ctx, requestId, request, response);
} else {
UInteger requestHandle = request.getRequestHeader().getRequestHandle();
sendServiceFault(ctx, requestId, requestHandle, fault);
}
});
stackServer.onServiceRequest(path, serviceRequest);
} catch (UaSerializationException e) {
logger.error("Error decoding UaRequestMessage", e);
sendServiceFault(ctx, requestId, uint(0), e);
} catch (Throwable t) {
logger.error("Unexpected error servicing UaRequestMessage", t);
long statusCode = UaException.extractStatusCode(t).map(StatusCode::getValue).orElse(StatusCodes.Bad_UnexpectedError);
sendServiceFault(ctx, requestId, uint(0), new UaException(statusCode, t));
} finally {
message.release();
buffersToDecode.clear();
}
});
}
}
}
use of org.eclipse.milo.opcua.stack.core.UaSerializationException in project milo by eclipse.
the class OpcUaBinaryStreamDecoder method readVariant.
public Variant readVariant() throws UaSerializationException {
if (depth.get() >= context.getEncodingLimits().getMaxRecursionDepth()) {
throw new UaSerializationException(StatusCodes.Bad_EncodingLimitsExceeded, "max recursion depth exceeded: " + context.getEncodingLimits().getMaxRecursionDepth());
}
depth.incrementAndGet();
try {
int encodingMask = buffer.readByte();
if (encodingMask == 0) {
return new Variant(null);
} else {
int typeId = encodingMask & 0x3F;
boolean dimensionsEncoded = (encodingMask & 0x40) == 0x40;
boolean arrayEncoded = (encodingMask & 0x80) == 0x80;
if (arrayEncoded) {
Class<?> backingClass = TypeUtil.getBackingClass(typeId);
int length = readInt32();
if (length == -1) {
return new Variant(null);
} else {
checkArrayLength(length);
Object flatArray = Array.newInstance(backingClass, length);
for (int i = 0; i < length; i++) {
Object element = decodeBuiltinType(typeId);
Array.set(flatArray, i, element);
}
int[] dimensions = dimensionsEncoded ? decodeDimensions() : new int[] { length };
Object array = dimensions.length > 1 ? ArrayUtil.unflatten(flatArray, dimensions) : flatArray;
return new Variant(array);
}
} else {
Object value = decodeBuiltinType(typeId);
return new Variant(value);
}
}
} finally {
depth.decrementAndGet();
}
}
Aggregations