Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a minimal rogue client detection mechanism at the transport level #2850

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Stack/Opc.Ua.Core/Stack/Tcp/TcpListenerChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/

using System;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -267,6 +268,17 @@

if (close)
{
// mark the RemoteAddress as potential rogue
if (reason.StatusCode == StatusCodes.BadSecurityChecksFailed || reason.StatusCode == StatusCodes.BadTcpMessageTypeInvalid)
{
var tcpTransportListener = m_listener as TcpTransportListener;

Check warning on line 274 in Stack/Opc.Ua.Core/Stack/Tcp/TcpListenerChannel.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpListenerChannel.cs#L272-L274

Added lines #L272 - L274 were not covered by tests
if (tcpTransportListener != null)
{
tcpTransportListener.MarkAsPotentialRogue
(((IPEndPoint)Socket.RemoteEndpoint).Address);
}
}

Check warning on line 281 in Stack/Opc.Ua.Core/Stack/Tcp/TcpListenerChannel.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpListenerChannel.cs#L281

Added line #L281 was not covered by tests
// close channel immediately.
ChannelFaulted();
}
Expand Down
257 changes: 256 additions & 1 deletion Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
Expand All @@ -37,6 +38,233 @@
}
}

/// <summary>
/// Represents a potential RogueClient
/// </summary>
public class RogueClient
{
#region Properties
/// <summary>
/// Time of the last recorded rogue action
/// </summary>
public int LastRogueActionTicks
{
get
{
return m_lastRogueActionTicks;
}

Check warning on line 55 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L55

Added line #L55 was not covered by tests
set
{
m_lastRogueActionTicks = value;
}
}

Check warning on line 60 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L59-L60

Added lines #L59 - L60 were not covered by tests

/// <summary>
/// Counter for number of rogue recorded actions
/// </summary>
public int RogueActionCount
{
get
{
return m_rogueActionCount;
}

Check warning on line 70 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L70

Added line #L70 was not covered by tests
set
{
m_rogueActionCount = value;
}
}

Check warning on line 75 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L74-L75

Added lines #L74 - L75 were not covered by tests

/// <summary>
/// Ticks until the client is Blocked
/// </summary>
public int BlockedUntilTicks
{
get
{
return m_blockedUntilTicks;
}

Check warning on line 85 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L85

Added line #L85 was not covered by tests
set
{
m_blockedUntilTicks = value;
}
}

Check warning on line 90 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L89-L90

Added lines #L89 - L90 were not covered by tests
#endregion

#region Private members
int m_lastRogueActionTicks;
int m_rogueActionCount;
int m_blockedUntilTicks;
#endregion
}

/// <summary>
/// Manages potential rogue clients
/// </summary>
public class RogueClientTracker : IDisposable
{
#region Public
/// <summary>
/// Constructor
/// </summary>
public RogueClientTracker()
{
m_cleanupTimer = new Timer(CleanupExpiredEntries, null, m_kCleanupIntervalMs, m_kCleanupIntervalMs);
}

Check warning on line 113 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L112-L113

Added lines #L112 - L113 were not covered by tests
/// <summary>
/// Checks if an IP address is currently blocked
/// </summary>
/// <param name="ipAddress"></param>
/// <returns></returns>
public bool IsBlocked(IPAddress ipAddress)
{
if (m_rogueClients.TryGetValue(ipAddress, out RogueClient client))
{
int currentTicks = HiResClock.TickCount;
return IsBlockedTicks(client.BlockedUntilTicks, currentTicks);
}

Check warning on line 125 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L124-L125

Added lines #L124 - L125 were not covered by tests
return false;
}

Check warning on line 127 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L127

Added line #L127 was not covered by tests

/// <summary>
/// Adds an action entry for a potential rogue client
/// </summary>
/// <param name="ipAddress"></param>
public void AddRogueClientAction(IPAddress ipAddress)
{
int currentTicks = HiResClock.TickCount;

Check warning on line 136 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L136

Added line #L136 was not covered by tests
m_rogueClients.AddOrUpdate(ipAddress,
// If client is new , create a new entry
key => new RogueClient {
LastRogueActionTicks = currentTicks,
RogueActionCount = 1,
BlockedUntilTicks = 0
},
// If the client exists, update its entry
(key, existingEntry) => {
// If IP currently blocked simply do nothing
if (IsBlockedTicks(existingEntry.BlockedUntilTicks, currentTicks))

Check warning on line 147 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L138-L147

Added lines #L138 - L147 were not covered by tests
{
return existingEntry;
}

// Elapsed time since last recorded action
int elapsedSinceLastRecAction = currentTicks - existingEntry.LastRogueActionTicks;

if (elapsedSinceLastRecAction <= m_kRogueIntervalMs)

Check warning on line 155 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L149-L155

Added lines #L149 - L155 were not covered by tests
{
existingEntry.RogueActionCount++;

if (existingEntry.RogueActionCount > m_kNrActionsTillBlock)

Check warning on line 159 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L157-L159

Added lines #L157 - L159 were not covered by tests
{
// Block the IP
existingEntry.BlockedUntilTicks = currentTicks + m_kBlockDurationMs;
Utils.LogError("RemoteClient IPAddress: {0} blocked for {1} ms due to exceeding {2} rogue actions under {3} ms ",
ipAddress.ToString(),
m_kBlockDurationMs,
m_kNrActionsTillBlock,
m_kRogueIntervalMs);

}
}
else
{
// Reset the count as the last action was outside the interval
existingEntry.RogueActionCount = 1;
}

existingEntry.LastRogueActionTicks = currentTicks;

return existingEntry;
}
);
}

Check warning on line 183 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L161-L183

Added lines #L161 - L183 were not covered by tests
/// <summary>
/// Dispose the cleanup timer
/// </summary>
public void Dispose()
{
m_cleanupTimer?.Dispose();
}

Check warning on line 191 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L191

Added line #L191 was not covered by tests
#endregion
#region Private methods

/// <summary>
/// Periodically cleans up expired RogueClientEntries to avoid memory leak and unblock clients whose duration has expired.
/// </summary>
/// <param name="state"></param>
private void CleanupExpiredEntries(object state)
{
int currentTicks = HiResClock.TickCount;

Check warning on line 202 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L202

Added line #L202 was not covered by tests
foreach (var entry in m_rogueClients)
romanett marked this conversation as resolved.
Show resolved Hide resolved
{
IPAddress clientIp = entry.Key;
RogueClient rClient = entry.Value;

Check warning on line 207 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L206-L207

Added lines #L206 - L207 were not covered by tests
// Unblock client if blocking duration has been exceeded
if (rClient.BlockedUntilTicks != 0 && !IsBlockedTicks(rClient.BlockedUntilTicks, currentTicks))
{
rClient.BlockedUntilTicks = 0;
rClient.RogueActionCount = 0;
Utils.LogInfo("Rogue Client with IP {0} is now unblocked, blocking duration of {1} ms has been exceeded",
clientIp.ToString(),
m_kBlockDurationMs);
}

Check warning on line 216 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L212-L216

Added lines #L212 - L216 were not covered by tests

// Remove clients that haven't had any rogue actions in the last m_kEntryExpirationMs interval
int elapsedSinceBadActionTicks = currentTicks - rClient.LastRogueActionTicks;
if (elapsedSinceBadActionTicks > m_kEntryExpirationMs)

Check warning on line 220 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L220

Added line #L220 was not covered by tests
{
// Even if TryRemove fails it will most probably succeed at the next execution
if (m_rogueClients.TryRemove(clientIp, out _))
{
Utils.LogInfo("Rogue Client with IP {0} is not tracked any longer, hasn't had rogue actions for more than {1} ms",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LogDebug would be better as well here I think

clientIp.ToString(),
m_kEntryExpirationMs);
}

Check warning on line 228 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L226-L228

Added lines #L226 - L228 were not covered by tests
}
}
}

Check warning on line 232 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L232

Added line #L232 was not covered by tests
/// <summary>
/// Determines if the IP is currently blocked based on the block expiration ticks and current ticks
/// </summary>
/// <param name="blockedUntilTicks"></param>
/// <param name="currentTicks"></param>
/// <returns></returns>
private bool IsBlockedTicks(int blockedUntilTicks, int currentTicks)
{
if (blockedUntilTicks == 0)
{
return false;
}

Check warning on line 244 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L244

Added line #L244 was not covered by tests
// C# signed arithmetic
int diff = blockedUntilTicks - currentTicks;
// If currentTicks < blockedUntilTicks then it is still blocked

Check warning on line 247 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L247

Added line #L247 was not covered by tests
// Works even if TickCount has wrapped around due to C# signed integer arithmetic
return diff > 0;
}

Check warning on line 250 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L250

Added line #L250 was not covered by tests


#endregion
#region Private members
private ConcurrentDictionary<IPAddress, RogueClient> m_rogueClients = new ConcurrentDictionary<IPAddress, RogueClient>();

Check warning on line 256 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L256

Added line #L256 was not covered by tests
private const int m_kRogueIntervalMs = 10_000;
private const int m_kNrActionsTillBlock = 3;

private const int m_kBlockDurationMs = 30_000; // 30 seconds
private const int m_kCleanupIntervalMs = 15_000;
private const int m_kEntryExpirationMs = 600_000; // 10 minutes

private Timer m_cleanupTimer;
#endregion
}

/// <summary>
/// Manages the transport for a UA TCP server.
/// </summary>
Expand Down Expand Up @@ -185,7 +413,7 @@
try
{
var channelIdString = globalChannelId.Substring(ListenerId.Length + 1);
var channelId = Convert.ToUInt32(channelIdString);

Check warning on line 416 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

The behavior of 'Convert.ToUInt32(string)' could vary based on the current user's locale settings. Replace this call in 'TcpTransportListener.UpdateChannelLastActiveTime(string)' with a call to 'Convert.ToUInt32(string, IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 416 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

The behavior of 'Convert.ToUInt32(string)' could vary based on the current user's locale settings. Replace this call in 'TcpTransportListener.UpdateChannelLastActiveTime(string)' with a call to 'Convert.ToUInt32(string, IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 416 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

The behavior of 'Convert.ToUInt32(string)' could vary based on the current user's locale settings. Replace this call in 'TcpTransportListener.UpdateChannelLastActiveTime(string)' with a call to 'Convert.ToUInt32(string, IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 416 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View workflow job for this annotation

GitHub Actions / test-windows-latest-Security.Certificates

The behavior of 'Convert.ToUInt32(string)' could vary based on the current user's locale settings. Replace this call in 'TcpTransportListener.UpdateChannelLastActiveTime(string)' with a call to 'Convert.ToUInt32(string, IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 416 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View workflow job for this annotation

GitHub Actions / test-windows-latest-Security.Certificates

The behavior of 'Convert.ToUInt32(string)' could vary based on the current user's locale settings. Replace this call in 'TcpTransportListener.UpdateChannelLastActiveTime(string)' with a call to 'Convert.ToUInt32(string, IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 416 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View workflow job for this annotation

GitHub Actions / test-windows-latest-Core

The behavior of 'Convert.ToUInt32(string)' could vary based on the current user's locale settings. Replace this call in 'TcpTransportListener.UpdateChannelLastActiveTime(string)' with a call to 'Convert.ToUInt32(string, IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 416 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View workflow job for this annotation

GitHub Actions / test-windows-latest-Client

The behavior of 'Convert.ToUInt32(string)' could vary based on the current user's locale settings. Replace this call in 'TcpTransportListener.UpdateChannelLastActiveTime(string)' with a call to 'Convert.ToUInt32(string, IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 416 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View workflow job for this annotation

GitHub Actions / test-windows-latest-Configuration

The behavior of 'Convert.ToUInt32(string)' could vary based on the current user's locale settings. Replace this call in 'TcpTransportListener.UpdateChannelLastActiveTime(string)' with a call to 'Convert.ToUInt32(string, IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 416 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View workflow job for this annotation

GitHub Actions / test-windows-latest-Client.ComplexTypes

The behavior of 'Convert.ToUInt32(string)' could vary based on the current user's locale settings. Replace this call in 'TcpTransportListener.UpdateChannelLastActiveTime(string)' with a call to 'Convert.ToUInt32(string, IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 416 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View workflow job for this annotation

GitHub Actions / test-windows-latest-Gds

The behavior of 'Convert.ToUInt32(string)' could vary based on the current user's locale settings. Replace this call in 'TcpTransportListener.UpdateChannelLastActiveTime(string)' with a call to 'Convert.ToUInt32(string, IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

Check warning on line 416 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View workflow job for this annotation

GitHub Actions / test-windows-latest-Server

The behavior of 'Convert.ToUInt32(string)' could vary based on the current user's locale settings. Replace this call in 'TcpTransportListener.UpdateChannelLastActiveTime(string)' with a call to 'Convert.ToUInt32(string, IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

TcpListenerChannel channel = null;
if (channelId > 0 &&
Expand Down Expand Up @@ -410,6 +638,8 @@
StatusCodes.BadNoCommunication,
"Failed to establish tcp listener sockets for Ipv4 and IPv6.");
}

m_rogueClientTracker = new RogueClientTracker();

Check warning on line 642 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L642

Added line #L642 was not covered by tests
}
}

Expand Down Expand Up @@ -497,16 +727,39 @@
}
#endregion

#region Internal
/// <summary>
/// Mark a remote endpoint as potential rogue

Check warning on line 732 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L732

Added line #L732 was not covered by tests
/// </summary>
/// <param name="remoteEndpoint"></param>
internal void MarkAsPotentialRogue(IPAddress remoteEndpoint)
{
Utils.LogError("MarkClientAsPotentialRogue address: {0} ", remoteEndpoint.ToString());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be LogDebug

m_rogueClientTracker.AddRogueClientAction(remoteEndpoint);
}
#endregion

#region Socket Event Handler
/// <summary>
/// Handles a new connection.
/// </summary>
private void OnAccept(object sender, SocketAsyncEventArgs e)
{

TcpListenerChannel channel = null;
bool repeatAccept = false;
do
{
bool isRogue = false;

// Filter out the RemoveAddresses which are detected with rogue behavior

Check warning on line 755 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L754-L755

Added lines #L754 - L755 were not covered by tests
if (m_rogueClientTracker.IsBlocked(((IPEndPoint)e.AcceptSocket.RemoteEndPoint).Address))
{
Utils.LogError("OnAccept: RemoteEndpoint address: {0} refused access for behaving as potential rogue ",

Check warning on line 758 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L758

Added line #L758 was not covered by tests
((IPEndPoint)e.AcceptSocket.RemoteEndPoint).Address.ToString());
isRogue = true;
}

repeatAccept = false;
lock (m_lock)
{
Expand All @@ -518,7 +771,7 @@
}

var channels = m_channels;
if (channels != null)
if (channels != null && !isRogue)

Check warning on line 774 in Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs

View check run for this annotation

Codecov / codecov/patch

Stack/Opc.Ua.Core/Stack/Tcp/TcpTransportListener.cs#L774

Added line #L774 was not covered by tests
{
// TODO: .Count is flagged as hotpath, implement separate counter
int channelCount = channels.Count;
Expand Down Expand Up @@ -806,6 +1059,8 @@
private int m_inactivityDetectPeriod;
private Timer m_inactivityDetectionTimer;
private int m_maxChannelCount;

private RogueClientTracker m_rogueClientTracker;
#endregion
}

Expand Down
Loading