none
WCF with NetNamedPipeBinding. Connect fails ongoing with Exception on specific machines RRS feed

  • Question

  • Hi,

    i'm just working on an issue that I have with WCF and NetNamedPipeBinding. I chose NetNamedPipeBinding since it's based on shared mem so it should be pretty fast. It worked good for a while. Now I have some customer machines that runs foreign windows services that also use WCF with NetNamedPipeBinding. Those services just Bind to net.pipe://localhost and run with admin-privileges. My own programs just run with standard user privileges. On any other machine this was no problem but on these machines, my services can't connect any longer. Host says, everything ok, Client tells me this:

    System.ServiceModel.EndpointNotFoundException: Es war kein an net.pipe://localhost/live/60a7ae59-2dc0-41e7-a371-04c8fe3485e9/documentService lauschender Endpunkt vorhanden, der die Nachricht annehmen konnte. Dies wird häufig durch eine fehlerhafte Adresse
     oder SOAP-Aktion verursacht. Weitere Details finden Sie unter "InnerException", sofern vorhanden.
    
    Server stack trace: 
       bei System.ServiceModel.Channels.ConnectionUpgradeHelper.DecodeFramingFault(ClientFramingDecoder decoder, IConnection connection, Uri via, String contentType, TimeoutHelper& timeoutHelper)
       bei System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
       bei System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
       bei System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
       bei System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
       bei System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       bei System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
       bei System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       bei System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
       bei System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
       bei System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
       bei System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
       bei System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
    
    Exception rethrown at [0]: 
       bei System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
       bei System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
       bei R.AlienInterfaces.Services.IDuplexBase.RegisterCallback()
       bei R.Aliens.Document_Pdf.DocumentServiceProxy..ctor(IDocumentServiceCallback documentServiceCallback, String serviceEndPoint)
       bei R.Aliens.Document_Pdf.DocumentModule.<Window_Loaded>b__0(Object o)
    

    So it seems that my client connects to foreign windows services that is running on the machines and listen to net.pipe://localhost. This service for sure knows nothing about my connections and my services and everything fails. What can I do to work around that the foreign windows service receives my requests for opening connections:

    My code:

    host:

              string pipeName = String.Format("net.pipe://localhost/{0}/{1}/", R.Common.Constants.Config.ProductCategory, pipeGuid);
              logger.Warn("pipe name = " + pipeName);
              var serviceHost = new ServiceHost(documentService);
    
              NetNamedPipeBinding nnpb = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
              nnpb.HostNameComparisonMode = HostNameComparisonMode.Exact;
              ServiceEndpoint serviceEndpoint = serviceHost.AddServiceEndpoint(typeof(IDocumentService), nnpb, pipeName + "documentService");
              serviceHost.Open();
    
    


    client:

        private class ConcreteDocumentServiceProxy : DuplexClientBase<IDocumentService> {
          // endpoint:          string pipeName = String.Format("net.pipe://localhost/{0}/{1}/documentService", R.Common.Constants.Config.ProductCategory, pipeGuid);
          public ConcreteDocumentServiceProxy(IDocumentServiceCallback cb, string endpoint)
            : base(cb, new ServiceEndpoint(ContractDescription.GetContract(typeof(IDocumentService)),
                new NetNamedPipeBinding(NetNamedPipeSecurityMode.None) { HostNameComparisonMode = System.ServiceModel.HostNameComparisonMode.Exact, MaxBufferPoolSize = 10000000, MaxBufferSize = 10000000, MaxReceivedMessageSize
     = 10000000 }, new EndpointAddress(endpoint))) {
            Channel.RegisterCallback();
          }
    ...
    }


    Since the foreign windows services runs as admin and binds to net.pipe://localhost with something like the following, I'm currently out of ideas:

    ServiceHost  sh = ServiceHost(..., new Uri("net.pipe://localhost"));
    ...


    What can I do to connect my two processes on these machines? I plan not to switch to another binding, since I don't know whatever limitations they have ...

    Thanks for your help!


    • Edited by mettex Friday, October 2, 2015 5:48 AM code formatting
    Thursday, October 1, 2015 1:40 PM

Answers

  • Hi all!

    So only to keep you up-to-date:

    I contacted the developers from the company who were responsible for opening the pipe in the "wrong" way. They were very kind and the fixed the misusage (bug) after a few mails of explanation.

    This seems to be the way of solving the problem...

    Kind regards,
      mettex

    PS: Bugfix from Microsoft still outstanding.

    • Marked as answer by mettex Wednesday, March 9, 2016 12:26 PM
    Wednesday, March 9, 2016 12:26 PM

All replies

  • Hi mettex,

    I am not understood you post's error message

    System.ServiceModel.EndpointNotFoundException: Es war kein an net.pipe://localhost/live/60a7ae59-2dc0-41e7-a371-04c8fe3485e9/documentService lauschender Endpunkt vorhanden, der die Nachricht annehmen konnte. Dies wird häufig durch eine fehlerhafte Adresse oder SOAP-Aktion verursacht. Weitere Details finden Sie unter "InnerException", sofern vorhanden

    It looks not like English.

    As far as I know the Named Pipes are not supposed to work outside of the machine hosting the service.

    But,for the stack trace I thought  client-side WCF channel stack failed when trying to derive from the service

    URL the actual name of the named pipe being used by the service.

    And,one possible cause is the service process doesn't have privilege to open a global named pipe,

    so it opens a local named pipe. You can refer to Dealing with OS privilege 'issues' in WCF Named Pipes scenarios

    When communication is required between different WCF applications on a single computer,

    and you want to prevent any communication from another machine, then use the named pipes transport.

    An additional restriction is that processes running from Windows Remote Desktop may be restricted to

    the same Windows Remote Desktop session unless they have elevated privileges.

    For more information, please refer to the following articles:

    1.Named pipe not found when using WCF netNamedPipeBinding

    2.Getting EndpointNotFoundException with NetNamedPipeBinding in C#; Need To Create Global Named Pipe

    3.What might cause EndpointNotFoundException on local WCF named pipes?

    I hope that will be helpful to you.

    Best Regards,

    Grady

    Friday, October 2, 2015 6:29 AM
    Moderator
  • Hi Grady,

    thank you so far. The text is in german since the customer machine is installed with german os. It just means that there was no endpoint listening at net.pipe.//...

    But the inner exception tells that DecodingFramingFault (etc.), which means, a connection was established but it couldn't locate the service. Isn't it?

    The point is, if i just turn off foreign service, everything is fine. Privileges, connections, everything. It just works. Turning the foreign service on, which seems to listen in net.pipe//localhost, my applications no longer find each other. Everything works in the same machine, so why can a completely different application disturb my connection in such a way, regardless which name I choose for my named pipe. Am I doing something wrong?

    Best regards,

      mettex

    Friday, October 2, 2015 9:08 AM
  • I just read through the articles and one article you gave me is:

    http://stackoverflow.com/questions/15981392/3rd-party-app-breaks-our-wcf-application/15987095#15987095

    I think, it explains what happens, but what is the solution? The solutions there are in my opinion not really a way to go (besides the last). I just copy from that thread:

    --------

    What can you do about it? I would suggest:

    • If the above hypothesis or something similar can be confirmed, and Garmin are using base+relative addressing with a base of just net.pipe://localhost, best would be to get them to own the problem: they could fix such a problem very easily by changing their base address to something more likely to be unique.
    • You could perhaps work around it by finding some way for your service application to run with the security privilege SeCreateGlobalPrivilege: this isn't easy without making it a Windows service or running As Administrator, but maybe not impossible. Then your metadata would also be published in the Global namespace and the client's search would find it before Garmin's.
    • [Later edit] Maybe there is a workaround involving setting the HostNameComparisonMode property of the binding to Exact, and using a synonym for localhost as the host part of the service URL (e.g. net.pipe://127.0.0.1/MyWCFConnection). This may steer the search around the Garmin variants so that your client has a chance to consider names in the Local session namespace. I don't know that it will work, but worth a try, I would have thought.
    • And a very long shot: Does your company have a product support relationship with Microsoft? Arguably this is a serious design flaw in WCF: if you make a fuss about it you might possibly get Microsoft to issue a QFE patch for it e.g. to provide a binding property to tell the client-side stack to only try the Local namespace.

    --------

    1. I, as a developer should now contact a another company, telling them, that they are using WCF in a wrong way and they break other communications ...?

    2. Elevating privileges is always a workaround, I can't do that with a serious application.

    3. Maybe a solution, but this sound like a fragile solution. The next one comes with the idea to open net.pipe://localhost and net.pipe://127.0.0.1 and I'm lost again. There are not that much synonyms ... :)

    4. Hm, this was written in 2013, has anyone chosen this solution? Would be great.

    So, do I get it correct, that any application that opens net.pipe://localhost can just be a major problem for my own application, since mine is not running as admin? So any company who doesn't really care about what they are doing in detail could be a possible problem for my own applications.


    • Edited by mettex Tuesday, October 6, 2015 5:53 AM corrected typo
    Friday, October 2, 2015 10:18 AM
  • Hi,

    are there any other ideas of how i can handle this problem? Is there a way of just deriving from NetNamedPipeBinding an by-pass the lookup-sequence? Can I somehow manipulate or suppress the lookup sequence so that it just connects to the one endpoint?

    Any more suggestions are very welcome.

    Best Regards,

      mettex

    Thursday, October 8, 2015 5:20 AM
  • Hi mettex,

    As far as I know, the NetNamedPipeBinding  just provides cross-process communication

    on the same machine. Named pipes do not work across machines.

    For more information, please refer to the following articles:

    1.NetNamedPipeBinding

    Best Regards,

    Grady

    Monday, October 19, 2015 6:33 AM
    Moderator
  • Hi Grady,

    thank you for the answer. But I'm on the same machine. All I want to reach now is that my two processes on the same machine find each other.

    It would be great if there is a workaround for this issue. Because it is an issue.

    Thank you and best regards,

      mettex

    Tuesday, October 20, 2015 5:20 AM
  • Hi mettex,

    Maybe you can try run your application as administrator.

    Best Regards,

    Grady

    Friday, October 23, 2015 6:49 AM
    Moderator
  • Hi grady,

    thank you for the reply, but as I said, this may be at best a _temporarly_ solution for just a moment, but - be honest - this can't be a serious solution for an application that should be installed on customer computers.

    Is there a way to create out of the thread a bug-report for WCF?

    Kind regards,

      mettex

    Friday, October 23, 2015 9:58 AM
  • Hi mettex,

    Yes, you can communication this case with Microsoft. You can refer to this net side

    https://connect.microsoft.com/

    Best Regards,

    Grady

     

    Wednesday, October 28, 2015 8:46 AM
    Moderator
  • Hi,

    i started a case here:

    https://connect.microsoft.com/VisualStudio/feedback/details/1932752

    Please, anyone, upvote it if you are using NetNamedPipeBinding. The problem can be easily reproduced with samples from Microsoft:

    WF_WCF_Samples\WCF\Basic\Binding\Net\NamedPipe\CS\

    I just did the following:

    1. Build client.exe and server.exe from sample

    2. Copy client.exe and client.exe.config as well as server.exe and server.exe.config into two different places. E.g. \default\ and \admin\

    3. Modify the client.exe.config and server.exe.config in the admin directory as follows:

    client.exe.config

    <?xml version="1.0"?>
    <configuration>
      <system.serviceModel>
        <client>
          <endpoint address="net.pipe://localhost/" binding="netNamedPipeBinding" contract="Microsoft.ServiceModel.Samples.ICalculator"/>
        </client>
      </system.serviceModel>
    <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
    

    server.exe.config

    <?xml version="1.0"?>
    <configuration>
      <system.serviceModel>
        <services>
          <service name="Microsoft.ServiceModel.Samples.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior">
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8000/ServiceModelSamples/service1"/>
              </baseAddresses>
            </host>
            <!-- this endpoint is exposed at the base address provided by host: net.pipe://localhost/ServiceModelSamples/service  -->
            <endpoint address="net.pipe://localhost/" binding="netNamedPipeBinding" bindingConfiguration="Binding1" contract="Microsoft.ServiceModel.Samples.ICalculator"/>
            <!-- the mex endpoint is exposed at http://localhost:8000/ServiceModelSamples/service/mex -->
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
          </service>
        </services>
        <bindings>
          <!-- 
                Following is the expanded configuration section for a NetNamedPipeBinding.
                Each property is configured with the default value.
             -->
          <netNamedPipeBinding>
            <binding name="Binding1" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
              <security mode="Transport">
                <transport protectionLevel="EncryptAndSign"/>
              </security>
            </binding>
          </netNamedPipeBinding>
        </bindings>
        <!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
        <behaviors>
          <serviceBehaviors>
            <behavior name="CalculatorServiceBehavior">
              <serviceMetadata httpGetEnabled="True"/>
              <serviceDebug includeExceptionDetailInFaults="False"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
    

    4. Now run admin\server.exe with admin-privileges (run as admin). admin\client.exe can easily connect to the server.

    5. Run default\server.exe (without admin privileges). default\client.exe CANNOT connect to it's server since it looks up admin\server.exe say's, "I know nothing about your services", and everything fails. If I now stop admin\server.exe, everything works fine. I also can start default\server.exe with admin privileges, but this is not possible in any case, in any situation, on any computer.

    As said in previous posts: The admin\server.exe could be any other application not from you and it stops your application from working.

    Any workaround is highly appriciated. I would be satisfied if I can manipulate the lookup so that there as at least no lookup at all, but just a connect between exactly my two applications.

    Kind regards,

      mettex

    Friday, November 6, 2015 7:01 AM
  • Hi all!

    So only to keep you up-to-date:

    I contacted the developers from the company who were responsible for opening the pipe in the "wrong" way. They were very kind and the fixed the misusage (bug) after a few mails of explanation.

    This seems to be the way of solving the problem...

    Kind regards,
      mettex

    PS: Bugfix from Microsoft still outstanding.

    • Marked as answer by mettex Wednesday, March 9, 2016 12:26 PM
    Wednesday, March 9, 2016 12:26 PM