Skip to content

Commit

Permalink
OPCFoundation#2055: System clock independent timeouts.
Browse files Browse the repository at this point in the history
This is a barely tested proof-of-concept for timeouts independent of the system clock.
  • Loading branch information
gailjkm committed Apr 18, 2023
1 parent 8da702d commit 4253c70
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 4 deletions.
15 changes: 13 additions & 2 deletions Stack/Opc.Ua.Core/Stack/Tcp/ChannelToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ public DateTime CreatedAt
set { m_createdAt = value; }
}

/// <summary>
/// When the token was created by the server (refers to the server's clock).
/// </summary>
public int CreatedAtTick
{
get { return m_createdAtTick; }
set { m_createdAtTick = value; }
}


/// <summary>
/// The lifetime of the token in milliseconds.
/// </summary>
Expand All @@ -73,7 +83,7 @@ public bool Expired
{
get
{
if (DateTime.UtcNow > m_createdAt.AddMilliseconds(m_lifetime))
if (Environment.TickCount - m_createdAtTick > m_lifetime)
{
return true;
}
Expand All @@ -89,7 +99,7 @@ public bool ActivationRequired
{
get
{
if (DateTime.UtcNow > m_createdAt.AddMilliseconds(m_lifetime * TcpMessageLimits.TokenActivationPeriod))
if (Environment.TickCount - m_createdAtTick > (m_lifetime * TcpMessageLimits.TokenActivationPeriod))
{
return true;
}
Expand Down Expand Up @@ -219,6 +229,7 @@ public HMAC ServerHmac
private uint m_channelId;
private uint m_tokenId;
private DateTime m_createdAt;
private int m_createdAtTick;
private int m_lifetime;
private byte[] m_clientNonce;
private byte[] m_serverNonce;
Expand Down
1 change: 1 addition & 0 deletions Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryChannel.Symmetric.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ protected ChannelToken CreateToken()
token.ChannelId = m_channelId;
token.TokenId = 0;
token.CreatedAt = DateTime.UtcNow;
token.CreatedAtTick = Environment.TickCount;
token.Lifetime = (int)Quotas.SecurityTokenLifetime;

Utils.LogInfo("ChannelId {0}: Token #{1} created. CreatedAt={2:HH:mm:ss.fff}. Lifetime={3}.",
Expand Down
4 changes: 2 additions & 2 deletions Stack/Opc.Ua.Core/Stack/Tcp/UaSCBinaryClientChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1162,9 +1162,9 @@ private void ScheduleTokenRenewal(ChannelToken token)
}

// calculate renewal timing based on token lifetime.
DateTime expiryTime = token.CreatedAt.AddMilliseconds(token.Lifetime);
int expiryTime = token.CreatedAtTick + token.Lifetime;

double timeToRenewal = ((expiryTime.Ticks - DateTime.UtcNow.Ticks) / TimeSpan.TicksPerMillisecond) * TcpMessageLimits.TokenRenewalPeriod;
double timeToRenewal = (expiryTime - Environment.TickCount) * TcpMessageLimits.TokenRenewalPeriod;

if (timeToRenewal < 0)
{
Expand Down

0 comments on commit 4253c70

Please sign in to comment.