Search code examples
c#wcf.net-4.0net.tcp

Why is my self-signed certificate not working?


How strange. Many months ago I wrote a WCF service, which I tested on my local machine over a secure Net.Tcp connection using a self-signed certificate; everything worked fine. Then I deployed to a cloud server using a real SSL certificate, and everything still works fine.

But now, I need to debug some code on my local box again, and something has changed such that my local WCF connection doesn't work anymore! (And no, the certificate has not expired!) After about 2 minutes, I get a EndpointNotFoundException:

Could not connect to net.tcp://mypc:8000/. The connection attempt lasted for a 
time span of 00:02:06.5152363. TCP error code 10060: A connection attempt failed 
because the connected party did not properly respond after a period of time, or 
established connection failed because connected host has failed to respond 
192.168.241.1:8000

Here's the code that creates the client side connection:

protected override IWebService CreateChannel() {
  var baseAddress = CommunicationManager.DebugMode ? SharedConstants.WEB_SERVER_TEST_URL : SharedConstants.WEB_SERVER_LIVE_URL;
  var factory = new DuplexChannelFactory<IWebService>(new InstanceContext(SiteServer.Instance));
  factory.Endpoint.Address = new EndpointAddress("net.tcp://{0}:{1}/".Fmt(baseAddress, SharedConstants.PORT_WEB_SERVICE));
  var binding = new NetTcpBinding(SecurityMode.Message);
  binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
  binding.SendTimeout = TimeSpan.FromMinutes(10);
  factory.Endpoint.Binding = binding;
  // to get past a strange error, do this:
  // (see http://geekswithblogs.net/RandyMichak/archive/2009/03/04/programattically-setting-the-maxitemsinobjectgraph-property-in-client.aspx)
  foreach (var op in factory.Endpoint.Contract.Operations) {
    var dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>();
    dataContractBehavior.NullOr(b => b.MaxItemsInObjectGraph = 2147483647);
  }

  var cred = SiteServer.GetCredentials();
  if (cred != null) {
    var u = factory.Credentials.UserName;
    u.UserName = cred.CustomerID.ToString();
    u.Password = cred.Password;
  }
  return factory.CreateChannel();
}

and here's the config of the server side:

<service name="MyProgram.WebService.WebService" behaviorConfiguration="mex">
  <endpoint address="net.tcp://localhost:8000" binding="netTcpBinding" contract="MyProgram.IWebService" bindingConfiguration="SecureBinding" name="MyEndPoint"></endpoint>
  <endpoint address="mex" binding="mexTcpBinding" name="MEX" contract="IMetadataExchange"/>
  <host>
    <baseAddresses>
      <add baseAddress="net.tcp://localhost:8000"/>
    </baseAddresses>
  </host>
</service>
...
<netTcpBinding>
  <binding name="SecureBinding" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647" portSharingEnabled="false" 
             maxBufferSize="2147483647" >
    <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
    <security mode="Message">
      <message clientCredentialType="UserName"/>
    </security>
  </binding>
</netTcpBinding>

Solution

  • Doh!

    I had updated my antivirus/firewall software since last debug session, and the new firewall was blocking me! Just opened the port, and everything is working fine. How embarrassing... :-o