private static async Task ListenForRequests(RPCPeer peer, string prefix, string path) { Program.DebugConsoleOutput($"Setting up listener ..."); var tp = new TypeSerializer(false, false); var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); socket.Connect(new SockRock.UnixEndPoint(prefix + path + "_fd")); Program.DebugConsoleOutput($"Connected to fd socket, reading initial data"); SpawnedServer server; // Start by reading and verifying the protocol intial data var buffer = new byte[1024]; var count = socket.Receive(buffer); Program.DebugConsoleOutput($"Got protocol data with {count} bytes"); using (var ms = new System.IO.MemoryStream(buffer, 0, count, false)) using (var bcs = new BinaryConverterStream(ms, tp, false)) { var desc = await bcs.ReadAnyAsync <InitialProtocolDescription>(); if (desc.Version != 1) { throw new Exception($"Expected protocol version 1, but got {desc.Version}"); } if (desc.RequestSignature != tp.GetShortTypeName(typeof(SocketRequest))) { throw new Exception($"Expected type name to be {tp.GetShortTypeName(typeof(SocketRequest))}, but it was {desc.RequestSignature}"); } if (!peer.RemoteHandler.TryGetLocalObject(desc.ServerHandle, out var obj) || obj == null) { throw new Exception($"Unable to find the instance with the given handle: {desc.ServerHandle}"); } server = obj as SpawnedServer; if (server == null) { throw new Exception($"Unable to find the instance with the given handle: {desc.ServerHandle}, got something that is not a server ..."); } } Program.DebugConsoleOutput($"Protocol verification completed, starting main loop"); // Prepare the handle var rchandle = socket.Handle.ToInt32(); try { // Use a single allocated buffer for all requests using (var ms = new System.IO.MemoryStream()) using (var bcs = new BinaryConverterStream(ms, tp, false)) { Program.DebugConsoleOutput("{0} Entering main loop", System.Diagnostics.Process.GetCurrentProcess().Id); while (socket.Connected) { try { // Get the next request from the socket Program.DebugConsoleOutput("{0} Getting file handle", System.Diagnostics.Process.GetCurrentProcess().Id); var req = SockRock.ScmRightsImplementation.recv_fds(rchandle); if (req == null) { Program.DebugConsoleOutput("{0} Socket closed", System.Diagnostics.Process.GetCurrentProcess().Id); break; } Program.DebugConsoleOutput("{0} Got request, parsing ...", System.Diagnostics.Process.GetCurrentProcess().Id); // Copy the buffer into the stream we read from ms.Position = 0; ms.Write(req.Item2, 0, req.Item2.Length); ms.Position = 0; // Extract the data var data = await bcs.ReadAnyAsync <SocketRequest>(); Program.DebugConsoleOutput("{0}, Decoded request, local handle is {1} remote handle is {2}", System.Diagnostics.Process.GetCurrentProcess().Id, req.Item1[0], data.Handle); // All set, fire the request Task.Run( () => server.HandleRequestSimple(req.Item1[0], new IPEndPoint(IPAddress.Parse(data.RemoteIP), data.RemotePort), data.LogTaskID) ).ContinueWith( _ => Program.DebugConsoleOutput("{0}: Request handling completed", System.Diagnostics.Process.GetCurrentProcess().Id) ); } catch (Exception ex) { Program.ConsoleOutput("{0}: Processing failed: {1}", System.Diagnostics.Process.GetCurrentProcess().Id, ex); return; } } } } finally { var st = DateTime.Now; Program.DebugConsoleOutput("{0}: Stopping spawned process", System.Diagnostics.Process.GetCurrentProcess().Id); server.Stop(TimeSpan.FromMinutes(5)); Program.DebugConsoleOutput("{0}: Stopped spawned process in {1}", System.Diagnostics.Process.GetCurrentProcess().Id, DateTime.Now - st); peer.Dispose(); Program.DebugConsoleOutput("{0}: Stopped peer in {1}", System.Diagnostics.Process.GetCurrentProcess().Id, DateTime.Now - st); } }
/// <summary> /// Terminates the remote instance /// </summary> public void Stop() { ShouldStop = true; m_peer.Dispose(); }