use of org.eclipse.milo.opcua.stack.core.channel.ChannelParameters in project milo by eclipse.
the class UascClientAcknowledgeHandler method onAcknowledge.
private void onAcknowledge(ChannelHandlerContext ctx, ByteBuf buffer) {
if (helloTimeout != null && !helloTimeout.cancel()) {
helloTimeout = null;
handshakeFuture.completeExceptionally(new UaException(StatusCodes.Bad_Timeout, "timed out waiting for acknowledge"));
ctx.close();
return;
}
logger.debug("Received Acknowledge message on channel={}.", ctx.channel());
// Skip messageType, chunkType, and messageSize
buffer.skipBytes(3 + 1 + 4);
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);
}
EncodingLimits encodingLimits = config.getEncodingLimits();
/* Our receive buffer size is determined by the remote send buffer size. */
long localReceiveBufferSize = Math.min(remoteSendBufferSize, encodingLimits.getMaxChunkSize());
/* Our send buffer size is determined by the remote receive buffer size. */
long localSendBufferSize = Math.min(remoteReceiveBufferSize, encodingLimits.getMaxChunkSize());
/* Max message size the remote can send us; not influenced by remote configuration. */
long localMaxMessageSize = encodingLimits.getMaxMessageSize();
/* Max chunk count the remote can send us; not influenced by remote configuration. */
long localMaxChunkCount = encodingLimits.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, client.getStaticSerializationContext());
UascClientMessageHandler handler = new UascClientMessageHandler(config, secureChannel, serializationQueue, handshakeFuture);
ctx.pipeline().addLast(handler);
});
}
use of org.eclipse.milo.opcua.stack.core.channel.ChannelParameters in project milo by eclipse.
the class ChunkSerializationTest method testSymmetric4096.
@Test
public void testSymmetric4096() throws Exception {
ChannelParameters parameters = defaultParameters;
ChunkEncoder encoder = new ChunkEncoder(parameters);
ChunkDecoder decoder = new ChunkDecoder(parameters, EncodingLimits.DEFAULT);
SecureChannel[] channels = generateChannels4096();
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();
for (int messageSize = 0; messageSize < 1024; messageSize++) {
byte[] messageBytes = new byte[messageSize];
for (int i = 0; i < messageBytes.length; i++) {
messageBytes[i] = (byte) i;
}
ByteBuf messageBuffer = BufferUtil.pooledBuffer().writeBytes(messageBytes);
List<ByteBuf> chunkBuffers = new ArrayList<>();
try {
ChunkEncoder.EncodedMessage message = encoder.encodeSymmetric(clientChannel, requestId.getAndIncrement(), messageBuffer, MessageType.OpenSecureChannel);
chunkBuffers.addAll(message.getMessageChunks());
} catch (MessageEncodeException e) {
fail("encoding error", e);
}
try {
ChunkDecoder.DecodedMessage decodedMessage = decoder.decodeSymmetric(serverChannel, chunkBuffers);
ByteBuf message = decodedMessage.getMessage();
messageBuffer.readerIndex(0);
assertEquals(message, messageBuffer);
ReferenceCountUtil.release(message);
ReferenceCountUtil.release(messageBuffer);
} catch (Throwable t) {
fail("decoding error", t);
}
}
}
use of org.eclipse.milo.opcua.stack.core.channel.ChannelParameters in project milo by eclipse.
the class ChunkSerializationTest method testAsymmetric4096.
@Test
public void testAsymmetric4096() throws Exception {
ChannelParameters parameters = defaultParameters;
ChunkEncoder encoder = new ChunkEncoder(parameters);
ChunkDecoder decoder = new ChunkDecoder(parameters, EncodingLimits.DEFAULT);
SecureChannel[] channels = generateChannels4096();
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();
for (int messageSize = 0; messageSize < 512; messageSize++) {
byte[] messageBytes = new byte[messageSize];
for (int i = 0; i < messageBytes.length; i++) {
messageBytes[i] = (byte) i;
}
ByteBuf messageBuffer = BufferUtil.pooledBuffer().writeBytes(messageBytes);
List<ByteBuf> chunkBuffers = new ArrayList<>();
try {
ChunkEncoder.EncodedMessage message = encoder.encodeAsymmetric(clientChannel, requestId.getAndIncrement(), messageBuffer, MessageType.OpenSecureChannel);
chunkBuffers.addAll(message.getMessageChunks());
} catch (MessageEncodeException e) {
fail("encoding error", e);
}
try {
ChunkDecoder.DecodedMessage decodedMessage = decoder.decodeAsymmetric(serverChannel, chunkBuffers);
ByteBuf message = decodedMessage.getMessage();
messageBuffer.readerIndex(0);
assertEquals(message, messageBuffer);
ReferenceCountUtil.release(message);
ReferenceCountUtil.release(messageBuffer);
} catch (Throwable t) {
fail("decoding error", t);
}
}
}
use of org.eclipse.milo.opcua.stack.core.channel.ChannelParameters in project milo by eclipse.
the class ChunkSerializationTest method testSymmetricMessage.
@Test(dataProvider = "getSymmetricSecurityParameters")
public void testSymmetricMessage(SecurityPolicy securityPolicy, MessageSecurityMode messageSecurity) throws Exception {
logger.info("Symmetric chunk serialization, " + "securityPolicy={}, messageSecurityMode={}", securityPolicy, messageSecurity);
ChannelParameters[] channelParameters = { smallParameters, defaultParameters, unlimitedChunkCountParameters, unlimitedMessageSizeParameters };
for (ChannelParameters parameters : channelParameters) {
int[] messageSizes = new int[] { 128, parameters.getRemoteMaxMessageSize() };
for (int messageSize : messageSizes) {
ChunkEncoder encoder = new ChunkEncoder(parameters);
ChunkDecoder decoder = new ChunkDecoder(parameters, EncodingLimits.DEFAULT);
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;
}
ByteBuf messageBuffer = BufferUtil.pooledBuffer().writeBytes(messageBytes);
List<ByteBuf> chunkBuffers = new ArrayList<>();
try {
ChunkEncoder.EncodedMessage message = encoder.encodeSymmetric(clientChannel, requestId.getAndIncrement(), messageBuffer, MessageType.SecureMessage);
chunkBuffers.addAll(message.getMessageChunks());
} catch (MessageEncodeException e) {
fail("encoding error", e);
}
try {
ChunkDecoder.DecodedMessage decodedMessage = decoder.decodeSymmetric(serverChannel, chunkBuffers);
ByteBuf message = decodedMessage.getMessage();
messageBuffer.readerIndex(0);
assertEquals(message, messageBuffer);
ReferenceCountUtil.release(messageBuffer);
ReferenceCountUtil.release(message);
} catch (Throwable t) {
fail("decoding error", t);
}
}
}
}
use of org.eclipse.milo.opcua.stack.core.channel.ChannelParameters in project milo by eclipse.
the class UascServerHelloHandler method onHello.
private void onHello(ChannelHandlerContext ctx, ByteBuf buffer) throws UaException {
logger.debug("[remote={}] Received Hello message.", ctx.channel().remoteAddress());
receivedHello = true;
final HelloMessage hello = TcpMessageDecoder.decodeHello(buffer);
String endpointUrl = hello.getEndpointUrl();
boolean endpointMatch = endpointUrl != null && stackServer.getEndpointDescriptions().stream().anyMatch(endpoint -> Objects.equals(EndpointUtil.getPath(endpointUrl), EndpointUtil.getPath(endpoint.getEndpointUrl())));
if (!endpointMatch) {
throw new UaException(StatusCodes.Bad_TcpEndpointUrlInvalid, "unrecognized endpoint url: " + endpointUrl);
}
ctx.channel().attr(ENDPOINT_URL_KEY).set(endpointUrl);
long remoteProtocolVersion = hello.getProtocolVersion();
long remoteReceiveBufferSize = hello.getReceiveBufferSize();
long remoteSendBufferSize = hello.getSendBufferSize();
long remoteMaxMessageSize = hello.getMaxMessageSize();
long remoteMaxChunkCount = hello.getMaxChunkCount();
if (remoteProtocolVersion < PROTOCOL_VERSION) {
throw new UaException(StatusCodes.Bad_ProtocolVersionUnsupported, "unsupported protocol version: " + remoteProtocolVersion);
}
EncodingLimits config = stackServer.getConfig().getEncodingLimits();
/* 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 chunk count the remote can send us; not influenced by remote configuration. */
long localMaxChunkCount = config.getMaxChunkCount();
/* Max message size the remote can send us. Determined by our max chunk count and receive buffer size. */
long localMaxMessageSize = Math.min(localReceiveBufferSize * localMaxChunkCount, config.getMaxMessageSize());
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));
SerializationQueue serializationQueue = new SerializationQueue(stackServer.getConfig().getExecutor(), parameters, stackServer.getSerializationContext());
ctx.pipeline().addLast(new UascServerAsymmetricHandler(stackServer, transportProfile, serializationQueue));
ctx.pipeline().remove(this);
logger.debug("[remote={}] Removed HelloHandler, added AsymmetricHandler.", ctx.channel().remoteAddress());
AcknowledgeMessage acknowledge = new AcknowledgeMessage(PROTOCOL_VERSION, localReceiveBufferSize, localSendBufferSize, localMaxMessageSize, localMaxChunkCount);
ByteBuf messageBuffer = TcpMessageEncoder.encode(acknowledge);
// Using ctx.executor() is necessary to ensure this handler is removed
// before the message can be written and another response arrives.
ctx.executor().execute(() -> ctx.writeAndFlush(messageBuffer));
logger.debug("[remote={}] Sent Acknowledge message.", ctx.channel().remoteAddress());
}
Aggregations