Recover gracefully if a matching port is unavailable.

R=rnystrom@google.com
BUG=dartbug.com/22673

Review URL: https://codereview.chromium.org//993743002
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f3d79a3..96b81c8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 1.3.1
+
+* `loopback()` and `loopbackSecure()` recover gracefully if an ephemeral port is
+  requested and the located port isn't available on both IPv4 and IPv6.
+
 ## 1.3.0
 
 * Add support for `HttpServer.autoCompress`.
diff --git a/lib/http_multi_server.dart b/lib/http_multi_server.dart
index 01e3ca8..fc87455 100644
--- a/lib/http_multi_server.dart
+++ b/lib/http_multi_server.dart
@@ -10,6 +10,15 @@
 import 'src/multi_headers.dart';
 import 'src/utils.dart';
 
+/// The error code for an error caused by a port already being in use.
+final _addressInUseErrno = _computeAddressInUseErrno();
+int _computeAddressInUseErrno() {
+  if (Platform.isWindows) return 10048;
+  if (Platform.isMacOS) return 48;
+  assert(Platform.isLinux);
+  return 98;
+}
+
 /// An implementation of `dart:io`'s [HttpServer] that wraps multiple servers
 /// and forwards methods to all of them.
 ///
@@ -134,6 +143,16 @@
       return bind(InternetAddress.LOOPBACK_IP_V6, v4Server.port)
           .then((v6Server) {
         return new HttpMultiServer([v4Server, v6Server]);
+      }).catchError((error) {
+        if (error is! SocketException) throw error;
+        if (error.osError.errno != _addressInUseErrno) throw error;
+        if (port != 0) throw error;
+
+        // A port being available on IPv4 doesn't necessarily mean that the same
+        // port is available on IPv6. If it's not (which is rare in practice),
+        // we try again until we find one that's available on both.
+        v4Server.close();
+        return _loopback(port, bind);
       });
     });
   }
diff --git a/pubspec.yaml b/pubspec.yaml
index b1a294f..8faaace 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: http_multi_server
-version: 1.3.0+1
+version: 1.3.1
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://github.com/dart-lang/http_multi_server
 description: