Note that there are some explanatory texts on larger screens.

plurals
  1. POWCF ServiceHost crashes when UserNamePasswordValidator takes too long to process
    text
    copied!<p>I have found a situation where a WCF client can crash a WCF ServiceHost if the ServiceHost has a UserNamePasswordValidator that takes a while to process. I would like to hear any suggestions on solutions before I go throw this at Microsoft.</p> <p>The steps to reproduce is:</p> <ol> <li>Open a channel</li> <li>Call an API method which takes 10 seconds to return.</li> <li>Close the channel before API method returns.</li> <li>API method returns. ServiceHost crashes.</li> </ol> <p>The above only happens if UserNamePasswordValidator takes a while to process (my example, 2 seconds sleep). If UserNamePasswordValidator returns immediately, the above situation changes:</p> <ol> <li>Open a channel</li> <li>Call an API method which takes 10 seconds to return.</li> <li>Close the channel before API method returns.</li> <li>Closing channel waits on pending API method call.</li> <li>API method returns.</li> <li>Channel gets closed. Everything is good.</li> </ol> <p>The client code is as follows:</p> <pre><code>public static void Main(string[] args) { var binding = new NetTcpBinding(SecurityMode.TransportWithMessageCredential); binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName; var identity = new DnsEndpointIdentity("Dummy"); var endpointAddress = new EndpointAddress(new Uri("net.tcp://localhost:5000/"), identity); var channelFactory = new ChannelFactory&lt;IService&gt;(binding, endpointAddress); channelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; channelFactory.Credentials.UserName.UserName = "foo"; channelFactory.Credentials.UserName.Password = "bar"; channelFactory.Open(); IService service = channelFactory.CreateChannel(); ThreadPool.QueueUserWorkItem(CallPingOnChannel, service); Thread.Sleep(TimeSpan.FromSeconds(1)); channelFactory.Close(); } private static void CallPingOnChannel(object state) { var result = ((state) as IService).Ping(); } </code></pre> <p>The ServiceHost is set up as follows:</p> <pre><code>public static void Main(string[] args) { var serviceHost = new ServiceHost(typeof(Service), TcpBaseAddress); serviceHost.Description.Behaviors.Add(new ErrorHandler()); var netTcpBinding = new NetTcpBinding(SecurityMode.TransportWithMessageCredential); netTcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate; netTcpBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName; serviceHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom; serviceHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new UserValidator(); serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; serviceHost.Credentials.ServiceCertificate.Certificate = GetCertificate(); serviceHost.AddServiceEndpoint(typeof(IService), netTcpBinding, ""); serviceHost.Open(); Console.ReadLine(); } </code></pre> <p>And the UserValidator is implemented as follows:</p> <pre><code>public class UserValidator : UserNamePasswordValidator { public override void Validate(string userName, string password) { Thread.Sleep(TimeSpan.FromSeconds(2)); } } </code></pre> <p>The unhandled exception which causes the main thread to crash is:</p> <pre><code>System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '10675199.02:48:05.4775807'. ---&gt; System.IO.IOException: The read operation failed, see inner exception. ---&gt; System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '10675199.02:48:05.4775807'. ---&gt; System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload