From 8010677a8b39545467844eb416460d35d88a7674 Mon Sep 17 00:00:00 2001 From: Mikhail Mitrofanov Date: Sat, 3 May 2025 22:27:40 +0300 Subject: [PATCH] Untrusted channel works, but it breaks trusted channel --- Example.Backend/Program.cs | 11 ++- Example.Frontend/Program.cs | 19 +++- mROA/Abstract/IUntrustedGateway.cs | 11 +++ .../Backend/NetworkGatewayModule.cs | 4 +- mROA/Implementation/Backend/UdpGateway.cs | 92 +++++++++++++++++++ mROA/Implementation/EMessageType.cs | 1 + .../Implementation/UdpUntrustedInteraction.cs | 20 +++- mROA/mROA.csproj | 2 +- 8 files changed, 147 insertions(+), 13 deletions(-) create mode 100644 mROA/Abstract/IUntrustedGateway.cs create mode 100644 mROA/Implementation/Backend/UdpGateway.cs diff --git a/Example.Backend/Program.cs b/Example.Backend/Program.cs index 719d274..4f5a7ab 100644 --- a/Example.Backend/Program.cs +++ b/Example.Backend/Program.cs @@ -19,9 +19,10 @@ class Program builder.Modules.Add(new BackendIdentityGenerator()); // builder.UseNetworkGateway(new IPEndPoint(IPAddress.Loopback, 4567), typeof(NextGenerationInteractionModule), // builder.GetModule()!); - builder.UseNetworkGateway(new IPEndPoint(IPAddress.Loopback, 4567), typeof(ChannelInteractionModule), + var listening = new IPEndPoint(IPAddress.Loopback, 4567); + builder.UseNetworkGateway(listening, typeof(ChannelInteractionModule), builder.GetModule()!); - + builder.Modules.Add(new UdpGateway(listening)); builder.Modules.Add(new ConnectionHub()); builder.Modules.Add(new HubRequestExtractor(typeof(RequestExtractor))); @@ -45,12 +46,12 @@ class Program builder.Build(); new RemoteTypeBinder(); - TransmissionConfig.RealContextRepository = builder.GetModule(); - TransmissionConfig.RemoteEndpointContextRepository = builder.GetModule(); + TransmissionConfig.RealContextRepository = builder.GetModule()!; + TransmissionConfig.RemoteEndpointContextRepository = builder.GetModule()!; TransmissionConfig.OwnershipRepository = new MultiClientOwnershipRepository(); + _ = builder.GetModule()!.Start(); var gateway = builder.GetModule(); - gateway.Run(); } } \ No newline at end of file diff --git a/Example.Frontend/Program.cs b/Example.Frontend/Program.cs index 97e7880..6dbf673 100644 --- a/Example.Frontend/Program.cs +++ b/Example.Frontend/Program.cs @@ -25,8 +25,10 @@ class Program builder.Modules.Add(new RemoteContextRepository()); builder.Modules.Add(new ChannelInteractionModule()); + builder.Modules.Add(new UdpUntrustedInteraction()); builder.Modules.Add(new RepresentationModule()); - builder.Modules.Add(new NetworkFrontendBridge(new IPEndPoint(IPAddress.Loopback, 4567))); + var serverEndPoint = new IPEndPoint(IPAddress.Loopback, 4567); + builder.Modules.Add(new NetworkFrontendBridge(serverEndPoint)); builder.Modules.Add(new StaticRepresentationModuleProducer()); builder.Modules.Add(new RequestExtractor()); builder.Modules.Add(new BasicExecutionModule()); @@ -43,10 +45,13 @@ class Program var frontendBridge = builder.GetModule()!; frontendBridge.Connect(); _ = builder.GetModule()!.StartExtraction(); + _ = builder.GetModule().Start(serverEndPoint); Console.WriteLine(TransmissionConfig.OwnershipRepository.GetOwnershipId()); var context = builder.GetModule(); - var factory = context.GetSingleObject(typeof(IPrinterFactory), -TransmissionConfig.OwnershipRepository.GetHostOwnershipId()) as IPrinterFactory; + var factory = + context.GetSingleObject(typeof(IPrinterFactory), + -TransmissionConfig.OwnershipRepository.GetHostOwnershipId()) as IPrinterFactory; using (var disposingPrinter = factory.Create("Test")) { @@ -66,6 +71,9 @@ class Program Thread.Sleep(100); + disposingPrinter.SomeoneIsApproaching("Mikhail"); + Console.WriteLine("Approaching detected"); + factory.Register(new ClientBasedPrinter()); DemoCheck.ClientBasedImplementation = true; Console.WriteLine("Registered printer"); @@ -102,6 +110,7 @@ class Program Console.WriteLine("Dispose printer"); } + DemoCheck.Dispose = true; @@ -116,12 +125,12 @@ class Program cts.Cancel(); Console.WriteLine($"Token state {cts.Token.IsCancellationRequested}"); DemoCheck.TaskCancelation = true; - + frontendBridge.Disconnect(); - + DemoCheck.Show(); Console.ReadKey(); - + // // const int iterations = 10000; // var timer = Stopwatch.StartNew(); diff --git a/mROA/Abstract/IUntrustedGateway.cs b/mROA/Abstract/IUntrustedGateway.cs new file mode 100644 index 0000000..9cb5fee --- /dev/null +++ b/mROA/Abstract/IUntrustedGateway.cs @@ -0,0 +1,11 @@ +using System; +using System.Net; +using System.Threading.Tasks; + +namespace mROA.Abstract +{ + public interface IUntrustedGateway : IInjectableModule, IDisposable + { + Task Start(); + } +} \ No newline at end of file diff --git a/mROA/Implementation/Backend/NetworkGatewayModule.cs b/mROA/Implementation/Backend/NetworkGatewayModule.cs index b01786c..9634fd1 100644 --- a/mROA/Implementation/Backend/NetworkGatewayModule.cs +++ b/mROA/Implementation/Backend/NetworkGatewayModule.cs @@ -18,6 +18,8 @@ namespace mROA.Implementation.Backend private ISerializationToolkit? _serialization; private Dictionary _extractorsCTS = new(); + + public NetworkGatewayModule(IPEndPoint endpoint, Type interactionModuleType, IInjectableModule[] injectableModules) { @@ -124,7 +126,7 @@ namespace mROA.Implementation.Backend } } } - + private void ThrowIfNotInjected() { if (_hub is null) diff --git a/mROA/Implementation/Backend/UdpGateway.cs b/mROA/Implementation/Backend/UdpGateway.cs new file mode 100644 index 0000000..86806cf --- /dev/null +++ b/mROA/Implementation/Backend/UdpGateway.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Channels; +using System.Threading.Tasks; +using mROA.Abstract; + +namespace mROA.Implementation.Backend +{ + public class UdpGateway : IUntrustedGateway + { + private IConnectionHub _hub; + private UdpClient _client; + private Dictionary _reservedPorts = new(); + private CancellationTokenSource _tokenSource = new(); + private ISerializationToolkit _serializationToolkit; + + public UdpGateway(IPEndPoint listeningEndpoint) + { + _client = new UdpClient(listeningEndpoint); + } + + + public void Inject(T dependency) + { + switch (dependency) + { + case IConnectionHub hub: + _hub = hub; + break; + case ISerializationToolkit serializationToolkit: + _serializationToolkit = serializationToolkit; + break; + } + } + + public void Dispose() + { + _tokenSource.Cancel(); + _client.Close(); + } + + public Task Start() + { + var token = _tokenSource.Token; + return Task.Run(async () => + { + while (token.IsCancellationRequested == false) + { + var incoming = await _client.ReceiveAsync(); + var parsed = _serializationToolkit.Deserialize(incoming.Buffer); + try + { + int channelId; + switch (parsed.MessageType) + { + case EMessageType.UntrustedConnect: + channelId = BitConverter.ToInt32(parsed.Data); + _reservedPorts[incoming.RemoteEndPoint] = channelId; + _ = UntrustedSend(_hub.GetInteraction(channelId), incoming.RemoteEndPoint); + break; + default: + channelId = _reservedPorts[incoming.RemoteEndPoint]; + var interaction = _hub.GetInteraction(channelId); + await interaction.ReceiveChanel.Writer.WriteAsync(parsed, token); + break; + } + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + }, token); + } + + private Task UntrustedSend(IChannelInteractionModule interaction, IPEndPoint endpoint) + { + return Task.Run(async () => + { + await foreach (var post in interaction.UntrustedPostChanel.ReadAllAsync()) + { + var parsed = _serializationToolkit.Serialize(post); + await _client.SendAsync(parsed, parsed.Length, endpoint); + } + } + ); + } + } +} \ No newline at end of file diff --git a/mROA/Implementation/EMessageType.cs b/mROA/Implementation/EMessageType.cs index bfb6304..d53aa72 100644 --- a/mROA/Implementation/EMessageType.cs +++ b/mROA/Implementation/EMessageType.cs @@ -12,5 +12,6 @@ namespace mROA.Implementation ClientRecovery, ClientConnect, ClientDisconnect, + UntrustedConnect, } } \ No newline at end of file diff --git a/mROA/Implementation/UdpUntrustedInteraction.cs b/mROA/Implementation/UdpUntrustedInteraction.cs index 84e067d..e66b526 100644 --- a/mROA/Implementation/UdpUntrustedInteraction.cs +++ b/mROA/Implementation/UdpUntrustedInteraction.cs @@ -12,6 +12,7 @@ namespace mROA.Implementation private ISerializationToolkit _serializationToolkit; private IChannelInteractionModule _channelInteractionModule; private CancellationTokenSource _tokenSource = new CancellationTokenSource(); + public void Dispose() { _tokenSource.Cancel(); @@ -35,19 +36,36 @@ namespace mROA.Implementation { var message = new Memory((await udpClient.ReceiveAsync()).Buffer); var parsed = _serializationToolkit.Deserialize(message.Span)!; + await writer.WriteAsync(parsed, token); } } private async Task Posting(UdpClient udpClient, CancellationToken token) { + var initMessage = new NetworkMessageHeader + { + MessageType = EMessageType.UntrustedConnect, Id = Guid.NewGuid(), + Data = BitConverter.GetBytes(Math.Abs(_channelInteractionModule.ConnectionId)) + }; + + var initParsed = _serializationToolkit.Serialize(initMessage); + + await udpClient.SendAsync(initParsed, initParsed.Length); + await foreach (var post in _channelInteractionModule.UntrustedPostChanel.ReadAllAsync(token)) { var serialized = _serializationToolkit.Serialize(post); +#if TRACE + Console.WriteLine("Untrusted write start"); +#endif await udpClient.SendAsync(serialized, serialized.Length); +#if TRACE + Console.WriteLine("Untrusted write finished"); +#endif } } - + public void Inject(T dependency) { switch (dependency) diff --git a/mROA/mROA.csproj b/mROA/mROA.csproj index c0682c2..3c172de 100644 --- a/mROA/mROA.csproj +++ b/mROA/mROA.csproj @@ -21,7 +21,7 @@ - ; +