[HttpListener] Only bind to the specified hosts (and support '*' as Any), fixes ...
authorMiguel de Icaza <miguel@gnome.org>
Wed, 12 Feb 2014 17:07:22 +0000 (12:07 -0500)
committerMiguel de Icaza <miguel@gnome.org>
Wed, 12 Feb 2014 17:08:10 +0000 (12:08 -0500)
mcs/class/System/System.Net/EndPointManager.cs
mcs/class/System/Test/System.Net/HttpListener2Test.cs

index eb4c79852c7269eba8ba196f6ba32c3eed43acb1..a4ee4a24ad13def9f5c74834acce2ded6f06ff6c 100644 (file)
@@ -82,9 +82,19 @@ namespace System.Net {
                static EndPointListener GetEPListener (string host, int port, HttpListener listener, bool secure)
                {
                        IPAddress addr;
-                       if (IPAddress.TryParse(host, out addr) == false)
+                       if (host == "*")
                                addr = IPAddress.Any;
-
+                       else if (IPAddress.TryParse(host, out addr) == false){
+                               try {
+                                       IPHostEntry iphost = Dns.GetHostByName(host);
+                                       if (iphost != null)
+                                               addr = iphost.AddressList[0];
+                                       else
+                                               addr = IPAddress.Any;
+                               } catch {
+                                       addr = IPAddress.Any;
+                               } 
+                       }
                        Hashtable p = null;  // Dictionary<int, EndPointListener>
                        if (ip_to_endpoints.ContainsKey (addr)) {
                                p = (Hashtable) ip_to_endpoints [addr];
index 6fefaa282f6210a1302dba31c578817f99e8a956..68d5da1d6a5bd9b251d9a725f8de773145634dec 100644 (file)
@@ -731,5 +731,43 @@ namespace MonoTests.System.Net {
                        t.Start ();
                        t.Stop ();
                }
+
+               //
+               // Bugs: #17204, #10818
+               //
+               // Sadly, on Unix, if there are different calls to bind
+               // like *:port and host:port that is not an error,
+               // it would only be an error if host:port is done twice, so
+               // the best we can hope for is that listening on a specific interface
+               // does not also listen to another interface.
+               //
+               [Test]
+               public void BindToSingleInterface ()
+               {
+                       var machineAddress = Dns.GetHostAddresses (Dns.GetHostName ());
+                       int port = 61234;
+                       var h = new HttpListener ();
+                       h.Prefixes.Add ("http://" + machineAddress [0] + ":" + port + "/");
+                       h.Start ();
+
+                       try {
+                               var c = new TcpClient ("localhost", port);
+                               Assert.Fail ("The TcpClient should have failed to connect since HttpListener is not listening on localhost");
+                       } catch (SocketException){
+                               // Pass
+                       }
+                       h.Stop ();
+               }
+
+               [Test]
+               public void BindToAllInterfaces ()
+               {
+                       var h = new HttpListener ();
+                       int port = 62234;
+                       h.Prefixes.Add ("http://*:" + port + "/");
+                       h.Start ();
+                       var c = new TcpClient ("localhost", port);
+                       h.Stop ();
+               }
        }
 }