Handle IPv6 literals in bssl client.

With IPv6, splitting a colon-separated host/port becomes more complicated.

Change-Id: I5073a5cbaa0714f2f8b9c837bb0809dd20304a3c
Reviewed-on: https://boringssl-review.googlesource.com/8441
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/tool/transport_common.cc b/tool/transport_common.cc
index 01fcde4..37bf0e0 100644
--- a/tool/transport_common.cc
+++ b/tool/transport_common.cc
@@ -72,9 +72,16 @@
 // in |hostname_and_port|, which should be of the form "www.example.com:123".
 // It returns true on success and false otherwise.
 bool Connect(int *out_sock, const std::string &hostname_and_port) {
-  const size_t colon_offset = hostname_and_port.find_last_of(':');
+  size_t colon_offset = hostname_and_port.find_last_of(':');
+  const size_t bracket_offset = hostname_and_port.find_last_of(']');
   std::string hostname, port;
 
+  // An IPv6 literal may have colons internally, guarded by square brackets.
+  if (bracket_offset != std::string::npos &&
+      colon_offset != std::string::npos && bracket_offset > colon_offset) {
+    colon_offset = std::string::npos;
+  }
+
   if (colon_offset == std::string::npos) {
     hostname = hostname_and_port;
     port = "443";
@@ -83,6 +90,12 @@
     port = hostname_and_port.substr(colon_offset + 1);
   }
 
+  // Handle IPv6 literals.
+  if (hostname.size() >= 2 && hostname[0] == '[' &&
+      hostname[hostname.size() - 1] == ']') {
+    hostname = hostname.substr(1, hostname.size() - 2);
+  }
+
   struct addrinfo hint, *result;
   memset(&hint, 0, sizeof(hint));
   hint.ai_family = AF_UNSPEC;