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

The server stops working #27

Open
Green7 opened this issue Sep 30, 2022 · 8 comments
Open

The server stops working #27

Green7 opened this issue Sep 30, 2022 · 8 comments
Labels
bug Something isn't working

Comments

@Green7
Copy link

Green7 commented Sep 30, 2022

Describe the bug

I am looking for a reliable named pipes server for communication between C ++ and C #.
Unfortunately, the H.Pipes server can easily crash due to an error in the client.
Here's an example code that shows how to make the server stop responding to new connections:

Steps to reproduce the bug

  1. Run ConsoleApp from samples as server
  2. Connect to server by the following code:
using System;
using System.IO.Pipes;
using System.Net;
using System.Threading;

namespace HPipeError
{
  internal class Program
  {
    private static void Main(string[] args)
    {
      var pipeClient = new NamedPipeClientStream("named_pipe_test_server");
      while (!pipeClient.IsConnected)
      {
        pipeClient.Connect();
        Thread.Sleep(100);
      }
      // read string length
      var buffer = new byte[sizeof(int)];
      pipeClient.Read(buffer, 0, sizeof(int));
      var len = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buffer, 0));
      // read string content
      buffer = new byte[len];
      pipeClient.Read(buffer, 0, len);
    }
  }
}
  1. After executing this code, try to connect to the server (e.g. using SampleApp as a client). It will be impossible.

Expected behavior

No response

Screenshots

No response

NuGet package version

No response

Platform

No response

IDE

No response

Additional context

Why is this happening?

After establishing the connection by the client, the server sends the name of the pipe created for the client through the main pipe.
The server then waits for the client to establish a connection to the newly created pipe, but unfortunately the main pipe is closed.
If the client fails to connect, the main pipe will not be recreated and you will not be able to connect to the server anymore.
So one malfunctioning client can therefore block the server.

@Green7 Green7 added the bug Something isn't working label Sep 30, 2022
@Green7
Copy link
Author

Green7 commented Oct 1, 2022

Ok, I'm waiting.

@Green7
Copy link
Author

Green7 commented Oct 4, 2022

There is another problem with the current server code when establishing a connection.
What is the situation like:
First, I connect to the main pipe and read the client connection pipe name from it.
Next I'm connecting to client connection pipe.
But this connection is not successful, I have to retry it or wait a few ms before trying to establish it.
Why is this happening? Because in the server code we have:

await handshakeWrapper.WriteAsync (Encoding.UTF8.GetBytes (connectionPipeName), token)

and then

// Wait for the client to connect to the data pipe
var connectionStream = CreatePipeStreamFunc? .Invoke (connectionPipeName) ?? PipeServerFactory.Create (connectionPipeName);

So we first send the client's connection name and then create a pipe with that name. If the client is fast (like C ++ code) it will read the name and try to connect before the server creates a pipe for client....

@Green7
Copy link
Author

Green7 commented Oct 4, 2022

I looked at the code and I think that a similar problem will also occur in the client.
If we restart the server when the client wants to read the name of the pipe created for it exception will occur and ReconnectionTimer.Stop() is called. So the AutoReconnect mechanism will not work anymore.
The solution to both problems seems to be moving the handshake code to PipeConnection class.

@darklajid
Copy link

I believe I ran into the same issue just now and can even kill the pipe (permanently, with no notice whatsoever) by accident. Is there a known workaround?

@alexeygritsenko
Copy link

@darklajid as a temporary you can use the server file with my fixes https://gist.github.com/alexeygritsenko/37499d4a5f36c31bf6db08e95675af8f

@HavenDV
Copy link
Owner

HavenDV commented Aug 16, 2023

Thanks for bringing this up. I will take a look now

HavenDV added a commit that referenced this issue Aug 16, 2023
@HavenDV
Copy link
Owner

HavenDV commented Aug 16, 2023

For now I added a test for this case and confirmed the issue.

@darklajid
Copy link

On top of the handshake issue (or maybe it's doing the same thing?) I also managed to kill the pipe without an error on the server side by running either accesschk or pipelist from the sysinternals suite (I ran both to figure out ACL issues and forgot which caused it: For one run the pipe is there, afterwards it's gone for good).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants