Files
romanett 8c52cba0b2 CTT reference server: faster alarm cycle in --ctt mode, MinSubscriptionLifetime 1000 ms (#4766)
Shortens CTT runs against the reference server without changing what the
CTT verifies.

## Changes
- **Alarm simulation step in `--ctt` mode: 1000 → 500 ms.**
`AlarmNodeManagerFactory.SimulationInterval` (default stays 1000 ms) is
passed to `AlarmNodeManager`; `ConsoleReferenceServer --ctt` sets it via
`Quickstarts.Servers.Utils.ConfigureCttModeNodeManagers()` to
`Utils.CttAlarmSimulationInterval` (500 ms) before the node managers are
created. A full alarm cycle (40 steps through all limits) takes 20 s
instead of 40 s. Every alarm still passes through all states and limits;
the alarm NodeIds carry the interval
(`…ExclusiveLevelAlarmType.500.Alarm` in CTT mode).
- **`Ctt.ReferenceServer.Config.xml`: `MinSubscriptionLifetime` 10000 →
1000 ms.** CTT scripts request short subscription lifetimes on purpose
and then wait for them to expire (Subscription Basic 063/016, Durable
012, Minimum 02 004, Publish Min 05 Err-001, Diagnostics 024); the 10 s
floor inflated those waits. Part 4 sets no minimum; the server still
enforces lifetime ≥ 3 × keep-alive.

## Measured (patched CTT 1.05.513 scripts)
| Part | Before | After |
| --- | ---: | ---: |
| A&C (p18), alarm step only + CTT Alarm Cycle Time 20 | 932 s | 576 s |
| Subscriptions (p16), MinSubscriptionLifetime only | 679 s | 579 s |

Combined full run with the matching CTT-side changes (ReadyToRun server
build, publish interval 150 ms, SecureChannel min lifetime 1000 ms, A&C
Refresh script waits): **72 → 54 min**, 0 regressions against the CTT
baseline (the only error is the known CTT-binary defect GDS 019).

The CTT CI repo derives its `Alarm Cycle Time` from
`Utils.CttAlarmSimulationInterval`, so runs against branches without
this change keep the old 30 s setting.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:49:18 +02:00

336 lines
17 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<ApplicationConfiguration
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ua="http://opcfoundation.org/UA/2008/02/Types.xsd"
xmlns="http://opcfoundation.org/UA/SDK/Configuration.xsd"
>
<!-- xsi:schemaLocation="http://opcfoundation.org/UA/SDK/Configuration.xsd ./Configuration.xsd" -->
<ApplicationName>Quickstart Reference Server (CTT)</ApplicationName>
<ApplicationUri>urn:localhost:UA:Quickstarts:ReferenceServer</ApplicationUri>
<ProductUri>uri:opcfoundation.org:Quickstarts:ReferenceServer</ProductUri>
<ApplicationType>Server_0</ApplicationType>
<SecurityConfiguration>
<!-- Which certificate types are supported -->
<ApplicationCertificates>
<CertificateIdentifier>
<StoreType>Directory</StoreType>
<StorePath>%LocalApplicationData%/OPC Foundation/pki/own</StorePath>
<SubjectName>CN=Quickstart Reference Server, C=US, S=Arizona, O=OPC Foundation, DC=localhost</SubjectName>
<CertificateTypeString>RsaSha256</CertificateTypeString>
</CertificateIdentifier>
</ApplicationCertificates>
<!-- Where the other application certificates are stored -->
<!-- Where the issuer certificate are stored (certificate authorities) -->
<TrustedIssuerCertificates>
<StoreType>Directory</StoreType>
<StorePath>%LocalApplicationData%/OPC Foundation/pki/issuer</StorePath>
</TrustedIssuerCertificates>
<!-- Where the trust list is stored -->
<TrustedPeerCertificates>
<StoreType>Directory</StoreType>
<StorePath>%LocalApplicationData%/OPC Foundation/pki/trusted</StorePath>
</TrustedPeerCertificates>
<!-- The directory used to store invalid certificates for later review by the administrator. -->
<RejectedCertificateStore>
<StoreType>Directory</StoreType>
<StorePath>%LocalApplicationData%/OPC Foundation/pki/rejected</StorePath>
</RejectedCertificateStore>
<MaxRejectedCertificates>5</MaxRejectedCertificates>
<!-- WARNING: The following setting (to automatically accept untrusted certificates) should be used
for easy debugging purposes ONLY and turned off for production deployments! -->
<AutoAcceptUntrustedCertificates>false</AutoAcceptUntrustedCertificates>
<!-- WARNING: SHA1 signed certificates are by default rejected and should be phased out.
only nano and embedded profiles are allowed to use sha1 signed certificates. -->
<RejectSHA1SignedCertificates>true</RejectSHA1SignedCertificates>
<RejectUnknownRevocationStatus>true</RejectUnknownRevocationStatus>
<MinimumCertificateKeySize>2048</MinimumCertificateKeySize>
<AddAppCertToTrustedStore>false</AddAppCertToTrustedStore>
<SendCertificateChain>true</SendCertificateChain>
<!-- Where the User issuer certificates are stored -->
<UserIssuerCertificates>
<StoreType>Directory</StoreType>
<StorePath>%LocalApplicationData%/OPC Foundation/pki/issuerUser</StorePath>
</UserIssuerCertificates>
<!-- Where the User trust list is stored-->
<TrustedUserCertificates>
<StoreType>Directory</StoreType>
<StorePath>%LocalApplicationData%/OPC Foundation/pki/trustedUser</StorePath>
</TrustedUserCertificates>
</SecurityConfiguration>
<TransportConfigurations></TransportConfigurations>
<TransportQuotas>
<OperationTimeout>120000</OperationTimeout>
<MaxStringLength>1048576</MaxStringLength>
<MaxByteStringLength>1048576</MaxByteStringLength>
<MaxArrayLength>65535</MaxArrayLength>
<MaxMessageSize>4194304</MaxMessageSize>
<MaxBufferSize>65535</MaxBufferSize>
<!--
Channels without traffic are closed after ChannelLifetime. CTT Security None 007.js and
Security Basic256Sha256 005.js keep SecureChannels without a Session idle for about 50 s
and expect the newest one to still be open (its SecurityToken is valid for at least 60 s).
-->
<ChannelLifetime>120000</ChannelLifetime>
<SecurityTokenLifetime>3600000</SecurityTokenLifetime>
</TransportQuotas>
<ServerConfiguration>
<BaseAddresses>
<ua:String>opc.tcp://localhost:62541/Quickstarts/ReferenceServer</ua:String>
<ua:String>opc.wss://localhost:62543/Quickstarts/ReferenceServer</ua:String>
</BaseAddresses>
<!--
These list the alternate addresses (via firewalls, multiple NICs etc.) that can be
used to communicate with the server. The URL used by the client when calling
FindServers/GetEndpoints or CreateSession will be used to filter the list of
endpoints returned by checking for alternate base addresses that have a domain
that matches the domain in the url provided by the client.
Note that any additional domains should be listed in the server's certificate. If they
are left out the client make refuse to connect because it has no way to know if the
alternate domain was authorized by the server administrator.
-->
<!--
<AlternateBaseAddresses>
<ua:String>opc.tcp://AlternateHostName/Quickstarts/ReferenceServer</ua:String>
<ua:String>opc.tcp://10.10.103.150/Quickstarts/ReferenceServer</ua:String>
<ua:String>opc.tcp://[2a01::626d]/Quickstarts/ReferenceServer</ua:String>
</AlternateBaseAddresses>
-->
<SecurityPolicies>
<ServerSecurityPolicy>
<SecurityMode>Sign_2</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
</ServerSecurityPolicy>
<ServerSecurityPolicy>
<SecurityMode>SignAndEncrypt_3</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
</ServerSecurityPolicy>
<ServerSecurityPolicy>
<SecurityMode>None_1</SecurityMode>
<SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#None</SecurityPolicyUri>
</ServerSecurityPolicy>
</SecurityPolicies>
<MinRequestThreadCount>5</MinRequestThreadCount>
<MaxRequestThreadCount>100</MaxRequestThreadCount>
<MaxQueuedRequestCount>2000</MaxQueuedRequestCount>
<!-- The SDK expects the server to support the same set of user tokens for every endpoint. -->
<UserTokenPolicies>
<!-- Allows anonymous users -->
<ua:UserTokenPolicy>
<ua:TokenType>Anonymous_0</ua:TokenType>
<!-- <ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#None</ua:SecurityPolicyUri> -->
</ua:UserTokenPolicy>
<!-- Allows username/password -->
<ua:UserTokenPolicy>
<ua:TokenType>UserName_1</ua:TokenType>
<!-- passwords must be encrypted - this specifies what algorithm to use -->
<!-- if no algorithm is specified, the active security policy is used -->
<!-- <ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</ua:SecurityPolicyUri> -->
</ua:UserTokenPolicy>
<!-- Allows user certificates -->
<ua:UserTokenPolicy>
<ua:TokenType>Certificate_2</ua:TokenType>
<!-- certificate possession must be proven with a digital signature - this specifies what algorithm to use -->
<!-- if no algorithm is specified, the active security policy is used -->
<!-- <ua:SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</ua:SecurityPolicyUri> -->
</ua:UserTokenPolicy>
</UserTokenPolicies>
<DiagnosticsEnabled>true</DiagnosticsEnabled>
<!-- Settings for CTT testing -->
<MaxSessionCount>75</MaxSessionCount>
<MaxChannelCount>1000</MaxChannelCount>
<MinSessionTimeout>10000</MinSessionTimeout>
<MaxSessionTimeout>3600000</MaxSessionTimeout>
<MaxBrowseContinuationPoints>10</MaxBrowseContinuationPoints>
<MaxQueryContinuationPoints>10</MaxQueryContinuationPoints>
<MaxHistoryContinuationPoints>100</MaxHistoryContinuationPoints>
<MaxRequestAge>600000</MaxRequestAge>
<MinPublishingInterval>50</MinPublishingInterval>
<MaxPublishingInterval>3600000</MaxPublishingInterval>
<PublishingResolution>50</PublishingResolution>
<MaxSubscriptionLifetime>3600000</MaxSubscriptionLifetime>
<MaxMessageQueueSize>100</MaxMessageQueueSize>
<MaxNotificationQueueSize>100</MaxNotificationQueueSize>
<MaxNotificationsPerPublish>1000</MaxNotificationsPerPublish>
<!-- The minimum sampling interval the server supports. 0 means the server does not
impose a server wide lower bound on the revised sampling interval. The value is
published in Server.ServerCapabilities.MinSupportedSampleRate. -->
<MinSupportedSamplingInterval>0</MinSupportedSamplingInterval>
<AvailableSamplingRates>
<SamplingRateGroup>
<Start>5</Start>
<Increment>5</Increment>
<Count>20</Count>
</SamplingRateGroup>
<SamplingRateGroup>
<Start>100</Start>
<Increment>100</Increment>
<Count>4</Count>
</SamplingRateGroup>
<SamplingRateGroup>
<Start>500</Start>
<Increment>250</Increment>
<Count>2</Count>
</SamplingRateGroup>
<SamplingRateGroup>
<Start>1000</Start>
<Increment>500</Increment>
<Count>20</Count>
</SamplingRateGroup>
</AvailableSamplingRates>
<RegistrationEndpoint>
<ua:EndpointUrl>opc.tcp://localhost:4840</ua:EndpointUrl>
<ua:Server>
<ua:ApplicationUri>opc.tcp://localhost:4840</ua:ApplicationUri>
<ua:ApplicationType>DiscoveryServer_3</ua:ApplicationType>
<ua:DiscoveryUrls>
<ua:String>opc.tcp://localhost:4840</ua:String>
</ua:DiscoveryUrls>
</ua:Server>
<ua:SecurityMode>SignAndEncrypt_3</ua:SecurityMode>
<ua:SecurityPolicyUri />
<ua:UserIdentityTokens />
</RegistrationEndpoint>
<MaxRegistrationInterval>0</MaxRegistrationInterval>
<NodeManagerSaveFile>Ctt.ReferenceServer.nodes.xml</NodeManagerSaveFile>
<!-- CTT scripts request short subscription lifetimes and wait for them to expire; Part 4 sets no minimum. -->
<MinSubscriptionLifetime>1000</MinSubscriptionLifetime>
<MaxPublishRequestCount>20</MaxPublishRequestCount>
<MaxSubscriptionCount>200</MaxSubscriptionCount>
<MaxEventQueueSize>10000</MaxEventQueueSize>
<!-- see https://opcfoundation-onlineapplications.org/profilereporting/ for list of available profiles -->
<ServerProfileArray>
<ua:String>http://opcfoundation.org/UA-Profile/Server/StandardUA2017</ua:String>
<ua:String>http://opcfoundation.org/UA-Profile/Server/DataAccess</ua:String>
<ua:String>http://opcfoundation.org/UA-Profile/Server/Methods</ua:String>
<ua:String>http://opcfoundation.org/UA-Profile/Server/ReverseConnect</ua:String>
<ua:String>http://opcfoundation.org/UA-Profile/Server/ClientRedundancy</ua:String>
<ua:String>http://opcfoundation.org/UA-Profile/Server/HistoricalRawData2022</ua:String>
<ua:String>http://opcfoundation.org/UA-Profile/Server/AggregateHistorical2022</ua:String>
</ServerProfileArray>
<ShutdownDelay>5</ShutdownDelay>
<ServerCapabilities>
<ua:String>DA</ua:String>
<ua:String>HD</ua:String>
<ua:String>AC</ua:String>
<ua:String>GDS</ua:String>
</ServerCapabilities>
<SupportedPrivateKeyFormats>
<ua:String>PFX</ua:String>
<ua:String>PEM</ua:String>
</SupportedPrivateKeyFormats>
<MaxTrustListSize>0</MaxTrustListSize>
<MultiCastDnsEnabled>false</MultiCastDnsEnabled>
<!-- Reverse connection parameters for aggregation server sample -->
<!--
<ReverseConnect>
<Clients>
<ReverseConnectClient>
<EndpointUrl>opc.tcp://localhost:65300</EndpointUrl>
<MaxSessionCount>0</MaxSessionCount>
<Enabled>true</Enabled>
</ReverseConnectClient>
</Clients>
<ConnectInterval>15000</ConnectInterval>
<ConnectTimeout>30000</ConnectTimeout>
<RejectTimeout>60000</RejectTimeout>
</ReverseConnect>
-->
<OperationLimits>
<MaxNodesPerRead>5000</MaxNodesPerRead>
<MaxNodesPerHistoryReadData>5000</MaxNodesPerHistoryReadData>
<MaxNodesPerHistoryReadEvents>5000</MaxNodesPerHistoryReadEvents>
<MaxNodesPerWrite>5000</MaxNodesPerWrite>
<MaxNodesPerHistoryUpdateData>5000</MaxNodesPerHistoryUpdateData>
<MaxNodesPerHistoryUpdateEvents>5000</MaxNodesPerHistoryUpdateEvents>
<MaxNodesPerMethodCall>5000</MaxNodesPerMethodCall>
<MaxNodesPerBrowse>5000</MaxNodesPerBrowse>
<MaxNodesPerRegisterNodes>5000</MaxNodesPerRegisterNodes>
<MaxNodesPerTranslateBrowsePathsToNodeIds>5000</MaxNodesPerTranslateBrowsePathsToNodeIds>
<MaxNodesPerNodeManagement>5000</MaxNodesPerNodeManagement>
<MaxMonitoredItemsPerCall>5000</MaxMonitoredItemsPerCall>
</OperationLimits>
<AuditingEnabled>true</AuditingEnabled>
<HttpsMutualTls>true</HttpsMutualTls>
<DurableSubscriptionsEnabled>true</DurableSubscriptionsEnabled>
<MaxDurableNotificationQueueSize>10000</MaxDurableNotificationQueueSize>
<MaxDurableEventQueueSize>10000</MaxDurableEventQueueSize>
<MaxDurableSubscriptionLifetimeInHours>10</MaxDurableSubscriptionLifetimeInHours>
<!-- The CTT deliberately sends a long run of invalid identity tokens in rapid
succession (e.g. the Security User X509 and User Name/Password negative
cases). Every rejected attempt - even one the CTT expects to fail - counts
toward the session manager's brute-force lockout, which is keyed on the
(shared) client application certificate thumbprint. With the default of 5
the lockout trips partway through the suite and every subsequent
ActivateSession returns BadUserAccessDenied, masking the real per-token
result (including the positive cases that expect Good). The lockout is a
vendor hardening feature, not an OPC UA conformance requirement, so it is
disabled here (0) for compliance testing. Production deployments keep the
default of 5. -->
<MaxFailedAuthenticationAttempts>0</MaxFailedAuthenticationAttempts>
</ServerConfiguration>
<Extensions>
<ua:XmlElement>
<GlobalDiscoveryServerConfiguration xmlns="http://opcfoundation.org/UA/GDS/Configuration.xsd">
<AuthoritiesStorePath>%LocalApplicationData%/OPC Foundation/GDS/authorities</AuthoritiesStorePath>
<ApplicationCertificatesStorePath>%LocalApplicationData%/OPC Foundation/GDS/applications</ApplicationCertificatesStorePath>
<DefaultSubjectNameContext>O=OPC Foundation</DefaultSubjectNameContext>
<CertificateGroups>
<CertificateGroupConfiguration>
<Id>Default</Id>
<CertificateTypes>
<ua:String>RsaSha256ApplicationCertificateType</ua:String>
</CertificateTypes>
<SubjectName>CN=Reference Server CA, O=OPC Foundation</SubjectName>
<BaseStorePath>%LocalApplicationData%/OPC Foundation/GDS/CA/default</BaseStorePath>
<DefaultCertificateLifetime>12</DefaultCertificateLifetime>
<DefaultCertificateKeySize>2048</DefaultCertificateKeySize>
<DefaultCertificateHashSize>256</DefaultCertificateHashSize>
<CACertificateLifetime>60</CACertificateLifetime>
<CACertificateKeySize>4096</CACertificateKeySize>
<CACertificateHashSize>512</CACertificateHashSize>
</CertificateGroupConfiguration>
</CertificateGroups>
<KnownHostNames />
<DatabaseStorePath></DatabaseStorePath>
<!-- GDS AliasName Server facet (OPC 10000-17 Annex C): merge the AliasNames of Servers
registered with the ALIAS capability (CTT GDS AliasName Discovery). -->
<EnableAliasNameAggregation>true</EnableAliasNameAggregation>
</GlobalDiscoveryServerConfiguration>
</ua:XmlElement>
<ua:XmlElement>
<MemoryBufferConfiguration xmlns="http://samples.org/UA/MemoryBuffer">
<Buffers>
<MemoryBufferInstance>
<Name>UInt32</Name>
<TagCount>100</TagCount>
<DataType>UInt32</DataType>
</MemoryBufferInstance>
<MemoryBufferInstance>
<Name>Double</Name>
<TagCount>100</TagCount>
<DataType>Double</DataType>
</MemoryBufferInstance>
</Buffers>
</MemoryBufferConfiguration>
</ua:XmlElement>
</Extensions>
<TraceConfiguration>
<OutputFilePath>./Logs/Ctt.ReferenceServer.log.txt</OutputFilePath>
<DeleteOnLoad>true</DeleteOnLoad>
<!-- Show Only Errors -->
<!-- <TraceMasks>1</TraceMasks> -->
<!-- Show Only Security and Errors -->
<!-- <TraceMasks>513</TraceMasks> -->
<!-- Show Only Security, Errors and Trace -->
<!-- <TraceMasks>515</TraceMasks> -->
<!-- Show Only Security, COM Calls, Errors and Trace -->
<!-- <TraceMasks>771</TraceMasks> -->
<!-- Show Only Security, Service Calls, Errors and Trace -->
<!-- <TraceMasks>523</TraceMasks> -->
<!-- Show Only Security, ServiceResultExceptions, Errors and Trace -->
<TraceMasks>519</TraceMasks>
</TraceConfiguration>
</ApplicationConfiguration>