0

I am trying to set up a WCF service which only accepts incoming messages/connection from itself.

I have been able to successfully create the service and run it and communicate with it using this code to create the WCF Endpoint (not restricted to localhost only)

NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.None;
_host = new ServiceHost(this, new Uri("net.tcp://localhost:19852"));
_host.Description.Behaviors.Add(new ServiceMetadataBehavior());
_host.AddServiceEndpoint(typeof(ISyncClient), binding, "SyncService");
_host.AddServiceEndpoint(typeof(IMetadataExchange), System.ServiceModel.Description.MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
_host.Open();

As soon as I add this line to restrict to connections from localhost

binding.HostNameComparisonMode = HostNameComparisonMode.Exact;

I get this exception

System.ServiceModel.AddressAlreadyInUseException: There is already a listener on IP endpoint 0.0.0.0:19852. This could happen if there is another application already listening on this endpoint or if you have multiple service endpoints in your service host with the same IP endpoint but with incompatible binding configurations. ---> System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted

I'm not even sure what I am doing is the correct way to restrict WCF access, but obviously its not working. To me this looks like some sort of conflict with the MEX endpoint. As far as I know I NEED the mex endpoint so I can't get rid of it. Anyone point me in the direction of a solution?

Malcolm O'Hare
  • 4,879
  • 3
  • 33
  • 53
  • When you say "set up a WCF service which only accepts incoming messages/connection from itself" what do you mean. I'm not sure I understand why you want to do this? Surely if you wanted to send yourself a message you would do it in proc rather than via a WCF channel. Anyway, have you checked to see that that port number is not already being used by another service? – stephenl Sep 11 '12 at 22:12
  • @stephenl What I mean is that I want the service to only accept connections from the same machine. – Malcolm O'Hare Sep 12 '12 at 12:22

1 Answers1

2

The easy way to do this is with a named pipe binding. It only supports local calls. From Choosing a Transport:

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.

Also, Mex points are completely optional. You can get rid of its endpoint and behavior without a problem.

ErnieL
  • 5,773
  • 1
  • 23
  • 27
  • When I was trying to test the service using WcfTestClient.exe it was not visible without the mex endpoint. – Malcolm O'Hare Sep 12 '12 at 12:23
  • Also, using a named pipe binding is not an option for this application (says my lead) – Malcolm O'Hare Sep 12 '12 at 12:31
  • Why is that? That's precisely what its for. Btw, the WcfTestClient needs the mex endpoint because there is no way for it to save the configuration (unlike your application). – stephenl Sep 12 '12 at 14:54
  • @Malcom - Is the requirement to accept only local calls is a security requirement? Relying on TCP message information for security purposes is not wise and likely vulnerable to spoofing (but I'm no security expert). If you can't use pipes and must use TCP I suggest looking into calling the service with use case specific credentials or claims. – ErnieL Sep 12 '12 at 16:27