Search in sources :

Example 1 with ChannelParameters

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);
    });
}
Also used : ChannelParameters(org.eclipse.milo.opcua.stack.core.channel.ChannelParameters) SerializationQueue(org.eclipse.milo.opcua.stack.core.channel.SerializationQueue) UaException(org.eclipse.milo.opcua.stack.core.UaException) AcknowledgeMessage(org.eclipse.milo.opcua.stack.core.channel.messages.AcknowledgeMessage) EncodingLimits(org.eclipse.milo.opcua.stack.core.channel.EncodingLimits)

Example 2 with ChannelParameters

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);
        }
    }
}
Also used : ServerSecureChannel(org.eclipse.milo.opcua.stack.core.channel.ServerSecureChannel) ChannelParameters(org.eclipse.milo.opcua.stack.core.channel.ChannelParameters) ChunkEncoder(org.eclipse.milo.opcua.stack.core.channel.ChunkEncoder) ClientSecureChannel(org.eclipse.milo.opcua.stack.client.transport.uasc.ClientSecureChannel) ArrayList(java.util.ArrayList) ServerSecureChannel(org.eclipse.milo.opcua.stack.core.channel.ServerSecureChannel) SecureChannel(org.eclipse.milo.opcua.stack.core.channel.SecureChannel) ClientSecureChannel(org.eclipse.milo.opcua.stack.client.transport.uasc.ClientSecureChannel) ByteBuf(io.netty.buffer.ByteBuf) ChunkDecoder(org.eclipse.milo.opcua.stack.core.channel.ChunkDecoder) LongSequence(org.eclipse.milo.opcua.stack.core.util.LongSequence) MessageEncodeException(org.eclipse.milo.opcua.stack.core.channel.MessageEncodeException) Test(org.testng.annotations.Test)

Example 3 with ChannelParameters

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);
        }
    }
}
Also used : ServerSecureChannel(org.eclipse.milo.opcua.stack.core.channel.ServerSecureChannel) ChannelParameters(org.eclipse.milo.opcua.stack.core.channel.ChannelParameters) ChunkEncoder(org.eclipse.milo.opcua.stack.core.channel.ChunkEncoder) ClientSecureChannel(org.eclipse.milo.opcua.stack.client.transport.uasc.ClientSecureChannel) ArrayList(java.util.ArrayList) ServerSecureChannel(org.eclipse.milo.opcua.stack.core.channel.ServerSecureChannel) SecureChannel(org.eclipse.milo.opcua.stack.core.channel.SecureChannel) ClientSecureChannel(org.eclipse.milo.opcua.stack.client.transport.uasc.ClientSecureChannel) ByteBuf(io.netty.buffer.ByteBuf) ChunkDecoder(org.eclipse.milo.opcua.stack.core.channel.ChunkDecoder) LongSequence(org.eclipse.milo.opcua.stack.core.util.LongSequence) MessageEncodeException(org.eclipse.milo.opcua.stack.core.channel.MessageEncodeException) Test(org.testng.annotations.Test)

Example 4 with ChannelParameters

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);
            }
        }
    }
}
Also used : ServerSecureChannel(org.eclipse.milo.opcua.stack.core.channel.ServerSecureChannel) ChannelParameters(org.eclipse.milo.opcua.stack.core.channel.ChannelParameters) ChunkEncoder(org.eclipse.milo.opcua.stack.core.channel.ChunkEncoder) ClientSecureChannel(org.eclipse.milo.opcua.stack.client.transport.uasc.ClientSecureChannel) ArrayList(java.util.ArrayList) ServerSecureChannel(org.eclipse.milo.opcua.stack.core.channel.ServerSecureChannel) SecureChannel(org.eclipse.milo.opcua.stack.core.channel.SecureChannel) ClientSecureChannel(org.eclipse.milo.opcua.stack.client.transport.uasc.ClientSecureChannel) ByteBuf(io.netty.buffer.ByteBuf) ChunkDecoder(org.eclipse.milo.opcua.stack.core.channel.ChunkDecoder) LongSequence(org.eclipse.milo.opcua.stack.core.util.LongSequence) MessageEncodeException(org.eclipse.milo.opcua.stack.core.channel.MessageEncodeException) Test(org.testng.annotations.Test)

Example 5 with ChannelParameters

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());
}
Also used : AttributeKey(io.netty.util.AttributeKey) ErrorMessage(org.eclipse.milo.opcua.stack.core.channel.messages.ErrorMessage) ExceptionHandler(org.eclipse.milo.opcua.stack.core.channel.ExceptionHandler) LoggerFactory(org.slf4j.LoggerFactory) HeaderDecoder(org.eclipse.milo.opcua.stack.core.channel.headers.HeaderDecoder) ChannelParameters(org.eclipse.milo.opcua.stack.core.channel.ChannelParameters) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) TcpMessageEncoder(org.eclipse.milo.opcua.stack.core.channel.messages.TcpMessageEncoder) ByteBuf(io.netty.buffer.ByteBuf) Stack(org.eclipse.milo.opcua.stack.core.Stack) HelloMessage(org.eclipse.milo.opcua.stack.core.channel.messages.HelloMessage) ByteToMessageDecoder(io.netty.handler.codec.ByteToMessageDecoder) UaStackServer(org.eclipse.milo.opcua.stack.server.UaStackServer) StatusCodes(org.eclipse.milo.opcua.stack.core.StatusCodes) TransportProfile(org.eclipse.milo.opcua.stack.core.transport.TransportProfile) Logger(org.slf4j.Logger) TcpMessageDecoder(org.eclipse.milo.opcua.stack.core.channel.messages.TcpMessageDecoder) EncodingLimits(org.eclipse.milo.opcua.stack.core.channel.EncodingLimits) AcknowledgeMessage(org.eclipse.milo.opcua.stack.core.channel.messages.AcknowledgeMessage) IOException(java.io.IOException) Ints(com.google.common.primitives.Ints) SerializationQueue(org.eclipse.milo.opcua.stack.core.channel.SerializationQueue) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) UaException(org.eclipse.milo.opcua.stack.core.UaException) MessageType(org.eclipse.milo.opcua.stack.core.channel.messages.MessageType) EndpointUtil(org.eclipse.milo.opcua.stack.core.util.EndpointUtil) ChannelParameters(org.eclipse.milo.opcua.stack.core.channel.ChannelParameters) HelloMessage(org.eclipse.milo.opcua.stack.core.channel.messages.HelloMessage) SerializationQueue(org.eclipse.milo.opcua.stack.core.channel.SerializationQueue) UaException(org.eclipse.milo.opcua.stack.core.UaException) AcknowledgeMessage(org.eclipse.milo.opcua.stack.core.channel.messages.AcknowledgeMessage) EncodingLimits(org.eclipse.milo.opcua.stack.core.channel.EncodingLimits) ByteBuf(io.netty.buffer.ByteBuf)

Aggregations

ChannelParameters (org.eclipse.milo.opcua.stack.core.channel.ChannelParameters)6 ByteBuf (io.netty.buffer.ByteBuf)5 ArrayList (java.util.ArrayList)4 ClientSecureChannel (org.eclipse.milo.opcua.stack.client.transport.uasc.ClientSecureChannel)4 ChunkDecoder (org.eclipse.milo.opcua.stack.core.channel.ChunkDecoder)4 ChunkEncoder (org.eclipse.milo.opcua.stack.core.channel.ChunkEncoder)4 MessageEncodeException (org.eclipse.milo.opcua.stack.core.channel.MessageEncodeException)4 SecureChannel (org.eclipse.milo.opcua.stack.core.channel.SecureChannel)4 ServerSecureChannel (org.eclipse.milo.opcua.stack.core.channel.ServerSecureChannel)4 LongSequence (org.eclipse.milo.opcua.stack.core.util.LongSequence)4 Test (org.testng.annotations.Test)4 UaException (org.eclipse.milo.opcua.stack.core.UaException)2 EncodingLimits (org.eclipse.milo.opcua.stack.core.channel.EncodingLimits)2 SerializationQueue (org.eclipse.milo.opcua.stack.core.channel.SerializationQueue)2 AcknowledgeMessage (org.eclipse.milo.opcua.stack.core.channel.messages.AcknowledgeMessage)2 Ints (com.google.common.primitives.Ints)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 ByteToMessageDecoder (io.netty.handler.codec.ByteToMessageDecoder)1 AttributeKey (io.netty.util.AttributeKey)1 IOException (java.io.IOException)1