示例#1
0
        public void RemoteReferences()
        {
            using (var setup = new ClientServerTester(FailMethod, FailMethod))
            {
                var client = new RPCPeer(setup.Client);
                var server = new RPCPeer(setup.Server, typeof(RemoteInvokeAble));

                // Let the client create proxy objects
                client.AddProxyGenerator((peer, type, handle) => new RemoteInvokeAbleProxy(peer, handle));

                // Let the server pass the object by reference
                server.TypeSerializer.RegisterSerializationAction(typeof(RemoteInvokeAble), SerializationAction.Reference);

                // Run the tests
                using (var proxy = client.InvokeRemoteMethodAsync <IRemoteInvokeAbleProxy>(0, typeof(RemoteInvokeAble).GetConstructor(new Type[0]), null, false).Result)
                {
                    if (proxy.Echo("test message") != "Echo : test message")
                    {
                        throw new Exception("Expected echo message back");
                    }

                    if (proxy.ID != 42)
                    {
                        throw new Exception("Expected 42 as the ID");
                    }

                    proxy.ID = 45;
                    if (proxy.ID != 45)
                    {
                        throw new Exception("Expected 45 as the ID");
                    }

                    if (proxy.CreateTime == 0)
                    {
                        throw new Exception("Expected a proxy creation time");
                    }

                    proxy.CreateTime = 0;
                    if (proxy.CreateTime != 0)
                    {
                        throw new Exception("Expected no proxy creation time");
                    }
                }
            }
        }
        private void HandleNewAddress(RPCPeer address, StateOfNeoContext db)
        {
            var    newNode    = default(Node);
            string successUrl = null;
            var    ports      = this.netSettings.GetPorts();

            foreach (var portWithType in ports)
            {
                var url = portWithType.GetFullUrl(address.Address.ToMatchedIp());

                try
                {
                    var rpcResult = RpcCaller.MakeRPCCall <RPCResponseBody <int> >(url, "getblockcount")
                                    .GetAwaiter()
                                    .GetResult();


                    if (rpcResult?.Result > 0)
                    {
                        successUrl = url;
                        newNode    = this.CreateNodeOfAddress(address.Address,
                                                              portWithType.Type,
                                                              successUrl,
                                                              NodeAddressType.RPC);
                        break;
                    }
                }
                catch (Exception e)
                {
                    Log.Error($"Get blockcount parse error {e.Message}", e);
                    break;
                }
            }

            if (newNode == default(Node))
            {
                var httpTypes = new string[] { "https", "http" };
                foreach (var httpType in httpTypes)
                {
                    var url            = $"{httpType}://{address.Address.ToMatchedIp()}";
                    var heightResponse = HttpRequester.MakeRestCall <HeightResponseObject>($@"{url}/api/main_net/v1/get_height", HttpMethod.Get)
                                         .GetAwaiter()
                                         .GetResult();

                    if (heightResponse != null)
                    {
                        successUrl = url;
                        newNode    = this.CreateNodeOfAddress(address.Address,
                                                              httpType,
                                                              successUrl,
                                                              NodeAddressType.REST,
                                                              NodeCallsConstants.NeoScan);
                        break;
                    }

                    var versionResponse = HttpRequester.MakeRestCall <NeoNotificationVersionResponse>($@"{url}/v1/version", HttpMethod.Get)
                                          .GetAwaiter()
                                          .GetResult();

                    if (versionResponse != null)
                    {
                        successUrl = url;
                        newNode    = this.CreateNodeOfAddress(address.Address,
                                                              httpType,
                                                              successUrl,
                                                              NodeAddressType.REST,
                                                              NodeCallsConstants.NeoNotification);
                        break;
                    }
                }
            }

            if (newNode != null)
            {
                var newNodeAddress = new NodeAddress
                {
                    Ip   = address.Address.ToMatchedIp(),
                    Node = newNode
                };

                var peer = db.Peers.FirstOrDefault(x => x.Ip == address.Address.ToMatchedIp());

                var result = LocationCaller.UpdateNode(newNode, newNodeAddress.Ip).GetAwaiter().GetResult();

                newNode.NodeAddresses.Add(newNodeAddress);

                db.NodeAddresses.Add(newNodeAddress);
                db.Nodes.Add(newNode);
                peer.Node = newNode;
                db.SaveChanges();
            }
        }
示例#3
0
        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);
            }
        }
 public void AddPeer(RPCPeer peer)
 {
     this.PeersCollected.Add(peer);
 }
示例#5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="T:Ceen.Httpd.Cli.SubProcess.SpawnRemoteInstance"/> class.
        /// </summary>
        /// <param name="path">The path to the config file</param>
        /// <param name="usessl">If set to <c>true</c> use ssl.</param>
        public SpawnRemoteInstance(string path, bool usessl, IStorageCreator storage, CancellationToken token)
        {
            m_path    = path;
            m_useSSL  = usessl;
            m_storage = storage;

            var prefix = m_hiddenSocketPath ? "\0" : string.Empty;
            var sockid = string.Format("ceen-socket-{0}", new Random().Next().ToString("x8"));

            if (m_hiddenSocketPath)
            {
                m_socketpath = sockid;
            }
            else
            {
                var pathPrefix = Environment.GetEnvironmentVariable("CEEN_SOCKET_FOLDER");
                if (string.IsNullOrWhiteSpace(pathPrefix))
                {
                    pathPrefix = System.IO.Path.GetTempPath();
                }

                m_socketpath = System.IO.Path.GetFullPath(System.IO.Path.Combine(pathPrefix, sockid));
            }

            // Setup a socket server, start the child, and stop the server
            using ((SystemHelper.IsCurrentOSPosix && !m_hiddenSocketPath) ? new DeleteFilesHelper(m_socketpath, m_socketpath + "_fd") : null)
                using (var serveripcsocket = SystemHelper.IsCurrentOSPosix ? new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP) : null)
                    using (var serverfdsocket = SystemHelper.IsCurrentOSPosix ? new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP) : null)
                    {
                        if (SystemHelper.IsCurrentOSPosix)
                        {
                            serveripcsocket.Bind(new SockRock.UnixEndPoint(prefix + m_socketpath));
                            serveripcsocket.Listen(1);

                            serverfdsocket.Bind(new SockRock.UnixEndPoint(prefix + m_socketpath + "_fd"));
                            serverfdsocket.Listen(1);
                        }

                        // Launch the child process
                        m_proc = StartRemoteProcess();

                        // TODO: Consider some multiplexer to allow multiple outputs without mixing the contents
                        var tasks = Task.WhenAll(
                            m_proc.StandardOutput.BaseStream.CopyToAsync(Console.OpenStandardOutput()),
                            m_proc.StandardError.BaseStream.CopyToAsync(Console.OpenStandardError()),
                            Console.OpenStandardInput().CopyToAsync(m_proc.StandardInput.BaseStream)
                            );

                        if (SystemHelper.IsCurrentOSPosix)
                        {
                            var ct = new CancellationTokenSource();

                            // Prepare cancellation after 5 seconds
                            Task.Delay(5000, ct.Token).ContinueWith(_ =>
                            {
                                serveripcsocket.Dispose();
                                serverfdsocket.Dispose();
                            });

                            // Get the first connection
                            m_ipcSocket = serveripcsocket.Accept();
                            m_fdSocket  = serverfdsocket.Accept();

                            // Stop the timer
                            ct.Cancel();
                        }

                        //and then don't listen anymore
                    }


            var ipc = new InterProcessConnection(new NetworkStream(m_ipcSocket, true));

            m_peer = new RPCPeer(
                ipc,
                typeof(IStorageEntry),
                typeof(IStorageCreator)
                );

            // We pass these by reference
            m_peer.TypeSerializer.RegisterSerializationAction(typeof(IStorageEntry), SerializationAction.Reference);
            m_peer.TypeSerializer.RegisterSerializationAction(typeof(IStorageCreator), SerializationAction.Reference);

            // Set up special handling for serializing an endpoint instance
            m_peer.TypeSerializer.RegisterEndPointSerializers();
            m_peer.TypeSerializer.RegisterIPEndPointSerializers();

            m_main = Task.Run(async() => {
                try
                {
                    using (m_fdSocket)
                        using (m_ipcSocket)
                            await ipc.RunMainLoopAsync(false);
                }
                finally
                {
                    Program.DebugConsoleOutput("{0}: Finished main loop, no longer connected to: {1}", System.Diagnostics.Process.GetCurrentProcess().Id, m_proc.Id);
                    m_proc.WaitForExit((int)TimeSpan.FromMinutes(1).TotalMilliseconds);
                    if (!m_proc.HasExited)
                    {
                        m_proc.Kill();
                    }
                    Program.DebugConsoleOutput("{0}: Target now stopped: {1}", System.Diagnostics.Process.GetCurrentProcess().Id, m_proc.Id);
                }
            });

            if (token.CanBeCanceled)
            {
                token.Register(() => this.Stop());
            }

            // Register the storage item, since it is a different concrete class (i.e. not the interface)
            if (storage != null)
            {
                m_peer.TypeSerializer.RegisterSerializationAction(storage.GetType(), SerializationAction.Reference);
                m_peer.RegisterLocalObjectOnRemote(storage, typeof(IStorageCreator)).Wait();
            }

            m_peer.AddAutomaticProxy(typeof(SpawnedServer), typeof(ISpawnedServerProxy));
            m_proxy = m_peer.CreateAsync <ISpawnedServerProxy>(typeof(SpawnedServer), usessl, path, storage).Result;

            if (SystemHelper.IsCurrentOSPosix)
            {
                // Prepare the file descriptor socket
                m_fdSocketTypeSerializer = new TypeSerializer(false, false);
                SetupDescriptorSocket().Wait();
            }
        }
示例#6
0
 public RemoteIntProxy(RPCPeer peer, long handle)
     : base(peer, typeof(RemoteInt), handle)
 {
 }
示例#7
0
        public void RemoteInvoke()
        {
            using (var setup = new ClientServerTester(FailMethod, FailMethod))
            {
                var client = new RPCPeer(setup.Client);
                var server = new RPCPeer(setup.Server, new Type[] { typeof(System.IO.Directory) }, (m, a) => m.Name == nameof(System.IO.Directory.GetCurrentDirectory));

                var result = client.InvokeRemoteMethodAsync <string>(0L, typeof(System.IO.Directory).GetMethod(nameof(System.IO.Directory.GetCurrentDirectory)), null, false).Result;
                if (result != System.IO.Directory.GetCurrentDirectory())
                {
                    throw new Exception("Failed to get the correct ");
                }

                Exception res = null;
                // Try unsupported type:
                try
                {
                    client.InvokeRemoteMethodAsync(0, typeof(System.IO.File).GetMethod(nameof(System.IO.File.Create)), new object[] { "test.txt" }, false).Wait();
                }
                catch (Exception ex)
                {
                    res = ex;
                }

                if (res == null)
                {
                    throw new Exception("Unwanted access to other type");
                }

                // Try other method
                res = null;
                try
                {
                    client.InvokeRemoteMethodAsync(0, typeof(System.IO.Directory).GetMethod(nameof(System.IO.Directory.CreateDirectory)), new object[] { "testdir" }, false).Wait();
                }
                catch (Exception ex)
                {
                    res = ex;
                }

                if (res == null)
                {
                    throw new Exception("Unwanted access to other method");
                }

                // Try invoking on the client
                res = null;
                try
                {
                    server.InvokeRemoteMethodAsync <string>(0, typeof(System.IO.Directory).GetMethod(nameof(System.IO.Directory.GetCurrentDirectory)), null, false).Wait();
                }
                catch (Exception ex)
                {
                    res = ex;
                }

                if (res == null)
                {
                    throw new Exception("Unwanted access to client method");
                }
            }
        }
示例#8
0
 public RemoteInvokeAbleProxy(RPCPeer peer, long handle)
     : base(peer, typeof(RemoteInvokeAble), handle)
 {
 }