689258
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
689258
From: Sergio Durigan Junior <sergiodj@redhat.com>
689258
Date: Fri, 18 May 2018 01:29:24 -0400
689258
Subject: gdb-rhbz881849-ipv6-1of3.patch
689258
689258
;; Implement IPv6 support for GDB/gdbserver (RH BZ 881849, Sergio Durigan Junior).
689258
689258
Implement IPv6 support for GDB/gdbserver
689258
689258
This patch implements IPv6 support for both GDB and gdbserver.  Based
689258
on my research, it is the fourth attempt to do that since 2006.  Since
689258
I used ideas from all of the previous patches, I also added their
689258
authors's names on the ChangeLogs as a way to recognize their
689258
efforts.  For reference sake, you can find the previous attempts at:
689258
689258
  https://sourceware.org/ml/gdb-patches/2006-09/msg00192.html
689258
689258
  https://sourceware.org/ml/gdb-patches/2014-02/msg00248.html
689258
689258
  https://sourceware.org/ml/gdb-patches/2016-02/msg00226.html
689258
689258
The basic idea behind the patch is to start using the new
689258
'getaddrinfo'/'getnameinfo' calls, which are responsible for
689258
translating names and addresses in a protocol-independent way.  This
689258
means that if we ever have a new version of the IP protocol, we won't
689258
need to change the code again (or, at least, won't have to change the
689258
majority of the code).
689258
689258
The function 'getaddrinfo' returns a linked list of possible addresses
689258
to connect to.  Dealing with multiple addresses proved to be a hard
689258
task with the current TCP auto-retry mechanism implemented on
689258
ser-tcp:net_open.  For example, when gdbserver listened only on an
689258
IPv4 socket:
689258
689258
  $ ./gdbserver --once 127.0.0.1:1234 ./a.out
689258
689258
and GDB was instructed to try to connect to both IPv6 and IPv4
689258
sockets:
689258
689258
  $ ./gdb -ex 'target extended-remote localhost:1234' ./a.out
689258
689258
the user would notice a somewhat big delay before GDB was able to
689258
connect to the IPv4 socket.  This happened because GDB was trying to
689258
connect to the IPv6 socket first, and had to wait until the connection
689258
timed out before it tried to connect to the IPv4 socket.
689258
689258
For that reason, I had to rewrite the main loop and implement a new
689258
method for handling multiple connections.  After some discussion,
689258
Pedro and I agreed on the following algorithm:
689258
689258
  1) For each entry returned by 'getaddrinfo', we try to open a socket
689258
  and connect to it.
689258
689258
  2.a) If we have a successful 'connect', we just use that connection.
689258
689258
  2.b) If we don't have a successfull 'connect', but if we've got a
689258
  ECONNREFUSED (meaning the the connection was refused), we keep track
689258
  of this fact by using a flag.
689258
689258
  2.c) If we don't have a successfull 'connect', but if we've got a
689258
  EINPROGRESS (meaning that the connection is in progress), we perform
689258
  a 'select' call on the socket until we have a result (either a
689258
  successful connection, or an error on the socket).
689258
689258
  3) If tcp_auto_retry is true, and we haven't gotten a successful
689258
  connection, and at least one of our attempts failed with
689258
  ECONNREFUSED, then we wait a little bit (i.e., call
689258
  'wait_for_connect'), check to see if there was a
689258
  timeout/interruption (in which case we bail out), and then go back
689258
  to (1).
689258
689258
After multiple tests, I was able to connect without delay on the
689258
scenario described above, and was also able to connect in all other
689258
types of scenarios.
689258
689258
I also implemented some hostname parsing functions (along with their
689258
corresponding unit tests) which are used to help GDB and gdbserver to
689258
parse hostname strings provided by the user.  These new functions are
689258
living inside common/netstuff.[ch].  I've had to do that since IPv6
689258
introduces a new URL scheme, which defines that square brackets can be
689258
used to enclose the host part and differentiate it from the
689258
port (e.g., "[::1]:1234" means "host ::1, port 1234").  I spent some
689258
time thinking about a reasonable way to interpret what the user wants,
689258
and I came up with the following:
689258
689258
  - If the user has provided a prefix that doesn't specify the protocol
689258
    version (i.e., "tcp:" or "udp:"), or if the user has not provided
689258
    any prefix, don't make any assumptions (i.e., assume AF_UNSPEC when
689258
    dealing with 'getaddrinfo') *unless* the host starts with "[" (in
689258
    which case, assume it's an IPv6 host).
689258
689258
  - If the user has provided a prefix that does specify the protocol
689258
    version (i.e., "tcp4:", "tcp6:", "udp4:" or "udp6:"), then respect
689258
    that.
689258
689258
This method doesn't follow strictly what RFC 2732 proposes (that
689258
literal IPv6 addresses should be provided enclosed in "[" and "]")
689258
because IPv6 addresses still can be provided without square brackets
689258
in our case, but since we have prefixes to specify protocol versions I
689258
think this is not an issue.
689258
689258
Another thing worth mentioning is the new 'GDB_TEST_SOCKETHOST'
689258
testcase parameter, which makes it possible to specify the
689258
hostname (without the port) to be used when testing GDB and
689258
gdbserver.  For example, to run IPv6 tests:
689258
689258
  $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]'
689258
689258
Or, to run IPv4 tests:
689258
689258
  $ make check-gdb RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp4:127.0.0.1'
689258
689258
This required a few changes on the gdbserver-base.exp, and also a
689258
minimal adjustment on gdb.server/run-without-local-binary.exp.
689258
689258
Finally, I've implemented a new testcase,
689258
gdb.server/server-connect.exp, which is supposed to run on the native
689258
host and perform various "smoke tests" using different connection
689258
methods.
689258
689258
This patch has been regression-tested on BuildBot and locally, and
689258
also built using a x86_64-w64-mingw32 GCC, and no problems were found.
689258
689258
gdb/ChangeLog:
689258
2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>
689258
	    Jan Kratochvil  <jan.kratochvil@redhat.com>
689258
	    Paul Fertser  <fercerpav@gmail.com>
689258
	    Tsutomu Seki  <sekiriki@gmail.com>
689258
	    Pedro Alves  <palves@redhat.com>
689258
689258
	* Makefile.in (SUBDIR_UNITTESTS_SRCS): Add
689258
	'unittests/parse-connection-spec-selftests.c'.
689258
	(COMMON_SFILES): Add 'common/netstuff.c'.
689258
	(HFILES_NO_SRCDIR): Add 'common/netstuff.h'.
689258
	* NEWS (Changes since GDB 8.2): Mention IPv6 support.
689258
	* common/netstuff.c: New file.
689258
	* common/netstuff.h: New file.
689258
	* ser-tcp.c: Include 'netstuff.h' and 'wspiapi.h'.
689258
	(wait_for_connect): Update comment.  New parameter
689258
	'gdb::optional<int> sock' instead of 'struct serial *scb'.
689258
	Use 'sock' directly instead of 'scb->fd'.
689258
	(try_connect): New function, with code from 'net_open'.
689258
	(net_open): Rewrite main loop to deal with multiple
689258
	sockets/addresses.  Handle IPv6-style hostnames; implement
689258
	support for IPv6 connections.
689258
	* unittests/parse-connection-spec-selftests.c: New file.
689258
689258
gdb/gdbserver/ChangeLog:
689258
2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>
689258
	    Jan Kratochvil  <jan.kratochvil@redhat.com>
689258
	    Paul Fertser  <fercerpav@gmail.com>
689258
	    Tsutomu Seki  <sekiriki@gmail.com>
689258
689258
	* Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'.
689258
	(OBS): Add 'common/netstuff.o'.
689258
	(GDBREPLAY_OBS): Likewise.
689258
	* gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'.
689258
	(remote_open): Implement support for IPv6
689258
	connections.
689258
	* remote-utils.c: Include 'netstuff.h', 'filestuff.h'
689258
	and 'wspiapi.h'.
689258
	(handle_accept_event): Accept connections from IPv6 sources.
689258
	(remote_prepare): Handle IPv6-style hostnames; implement
689258
	support for IPv6 connections.
689258
	(remote_open): Implement support for printing connections from
689258
	IPv6 sources.
689258
689258
gdb/testsuite/ChangeLog:
689258
2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>
689258
	    Jan Kratochvil  <jan.kratochvil@redhat.com>
689258
	    Paul Fertser  <fercerpav@gmail.com>
689258
	    Tsutomu Seki  <sekiriki@gmail.com>
689258
689258
	* README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST'
689258
	parameter.
689258
	* boards/native-extended-gdbserver.exp: Do not set 'sockethost'
689258
	by default.
689258
	* boards/native-gdbserver.exp: Likewise.
689258
	* gdb.server/run-without-local-binary.exp: Improve regexp used
689258
	for detecting when a remote debugging connection succeeds.
689258
	* gdb.server/server-connect.exp: New file.
689258
	* lib/gdbserver-support.exp (gdbserver_default_get_comm_port):
689258
	Do not prefix the port number with ":".
689258
	(gdbserver_start): New global GDB_TEST_SOCKETHOST.  Implement
689258
	support for detecting and using it.  Add '$debughost_gdbserver'
689258
	to the list of arguments used to start gdbserver.  Handle case
689258
	when gdbserver cannot resolve a network name.
689258
689258
gdb/doc/ChangeLog:
689258
2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>
689258
	    Jan Kratochvil  <jan.kratochvil@redhat.com>
689258
	    Paul Fertser  <fercerpav@gmail.com>
689258
	    Tsutomu Seki  <sekiriki@gmail.com>
689258
689258
	* gdb.texinfo (Remote Connection Commands): Add explanation
689258
	about new IPv6 support.  Add new connection prefixes.
689258
689258
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
689258
--- a/gdb/Makefile.in
689258
+++ b/gdb/Makefile.in
689258
@@ -430,6 +430,7 @@ SUBDIR_UNITTESTS_SRCS = \
689258
 	unittests/offset-type-selftests.c \
689258
 	unittests/observable-selftests.c \
689258
 	unittests/optional-selftests.c \
689258
+	unittests/parse-connection-spec-selftests.c \
689258
 	unittests/ptid-selftests.c \
689258
 	unittests/rsp-low-selftests.c \
689258
 	unittests/scoped_fd-selftests.c \
689258
@@ -967,6 +968,7 @@ COMMON_SFILES = \
689258
 	common/job-control.c \
689258
 	common/gdb_tilde_expand.c \
689258
 	common/gdb_vecs.c \
689258
+	common/netstuff.c \
689258
 	common/new-op.c \
689258
 	common/pathstuff.c \
689258
 	common/print-utils.c \
689258
@@ -1448,6 +1450,7 @@ HFILES_NO_SRCDIR = \
689258
 	common/gdb_vecs.h \
689258
 	common/gdb_wait.h \
689258
 	common/common-inferior.h \
689258
+	common/netstuff.h \
689258
 	common/host-defs.h \
689258
 	common/pathstuff.h \
689258
 	common/print-utils.h \
689258
diff --git a/gdb/NEWS b/gdb/NEWS
689258
--- a/gdb/NEWS
689258
+++ b/gdb/NEWS
689258
@@ -1,6 +1,12 @@
689258
 		What has changed in GDB?
689258
 	     (Organized release by release)
689258
 
689258
+*** Changes since GDB 8.2
689258
+
689258
+* GDB and GDBserver now support IPv6 connections.  IPv6 addresses
689258
+  can be passed using the '[ADDRESS]:PORT' notation, or the regular
689258
+  'ADDRESS:PORT' method.
689258
+
689258
 *** Changes in GDB 8.2
689258
 
689258
 * The 'set disassembler-options' command now supports specifying options
689258
diff --git a/gdb/common/netstuff.c b/gdb/common/netstuff.c
689258
new file mode 100644
689258
--- /dev/null
689258
+++ b/gdb/common/netstuff.c
689258
@@ -0,0 +1,155 @@
689258
+/* Operations on network stuff.
689258
+   Copyright (C) 2018 Free Software Foundation, Inc.
689258
+
689258
+   This file is part of GDB.
689258
+
689258
+   This program is free software; you can redistribute it and/or modify
689258
+   it under the terms of the GNU General Public License as published by
689258
+   the Free Software Foundation; either version 3 of the License, or
689258
+   (at your option) any later version.
689258
+
689258
+   This program is distributed in the hope that it will be useful,
689258
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
689258
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
689258
+   GNU General Public License for more details.
689258
+
689258
+   You should have received a copy of the GNU General Public License
689258
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
689258
+
689258
+#include "common-defs.h"
689258
+#include "netstuff.h"
689258
+#include <algorithm>
689258
+
689258
+#ifdef USE_WIN32API
689258
+#include <winsock2.h>
689258
+#include <wspiapi.h>
689258
+#else
689258
+#include <netinet/in.h>
689258
+#include <arpa/inet.h>
689258
+#include <netdb.h>
689258
+#include <sys/socket.h>
689258
+#include <netinet/tcp.h>
689258
+#endif
689258
+
689258
+/* See common/netstuff.h.  */
689258
+
689258
+scoped_free_addrinfo::~scoped_free_addrinfo ()
689258
+{
689258
+  freeaddrinfo (m_res);
689258
+}
689258
+
689258
+/* See common/netstuff.h.  */
689258
+
689258
+parsed_connection_spec
689258
+parse_connection_spec_without_prefix (std::string spec, struct addrinfo *hint)
689258
+{
689258
+  parsed_connection_spec ret;
689258
+  size_t last_colon_pos = 0;
689258
+  /* We're dealing with IPv6 if:
689258
+
689258
+     - ai_family is AF_INET6, or
689258
+     - ai_family is not AF_INET, and
689258
+       - spec[0] is '[', or
689258
+       - the number of ':' on spec is greater than 1.  */
689258
+  bool is_ipv6 = (hint->ai_family == AF_INET6
689258
+		  || (hint->ai_family != AF_INET
689258
+		      && (spec[0] == '['
689258
+			  || std::count (spec.begin (),
689258
+					 spec.end (), ':') > 1)));
689258
+
689258
+  if (is_ipv6)
689258
+    {
689258
+      if (spec[0] == '[')
689258
+	{
689258
+	  /* IPv6 addresses can be written as '[ADDR]:PORT', and we
689258
+	     support this notation.  */
689258
+	  size_t close_bracket_pos = spec.find_first_of (']');
689258
+
689258
+	  if (close_bracket_pos == std::string::npos)
689258
+	    error (_("Missing close bracket in hostname '%s'"),
689258
+		   spec.c_str ());
689258
+
689258
+	  hint->ai_family = AF_INET6;
689258
+
689258
+	  const char c = spec[close_bracket_pos + 1];
689258
+
689258
+	  if (c == '\0')
689258
+	    last_colon_pos = std::string::npos;
689258
+	  else if (c != ':')
689258
+	    error (_("Invalid cruft after close bracket in '%s'"),
689258
+		   spec.c_str ());
689258
+
689258
+	  /* Erase both '[' and ']'.  */
689258
+	  spec.erase (0, 1);
689258
+	  spec.erase (close_bracket_pos - 1, 1);
689258
+	}
689258
+      else if (spec.find_first_of (']') != std::string::npos)
689258
+	error (_("Missing open bracket in hostname '%s'"),
689258
+	       spec.c_str ());
689258
+    }
689258
+
689258
+  if (last_colon_pos == 0)
689258
+    last_colon_pos = spec.find_last_of (':');
689258
+
689258
+  /* The length of the hostname part.  */
689258
+  size_t host_len;
689258
+
689258
+  if (last_colon_pos != std::string::npos)
689258
+    {
689258
+      /* The user has provided a port.  */
689258
+      host_len = last_colon_pos;
689258
+      ret.port_str = spec.substr (last_colon_pos + 1);
689258
+    }
689258
+  else
689258
+    host_len = spec.size ();
689258
+
689258
+  ret.host_str = spec.substr (0, host_len);
689258
+
689258
+  /* Default hostname is localhost.  */
689258
+  if (ret.host_str.empty ())
689258
+    ret.host_str = "localhost";
689258
+
689258
+  return ret;
689258
+}
689258
+
689258
+/* See common/netstuff.h.  */
689258
+
689258
+parsed_connection_spec
689258
+parse_connection_spec (const char *spec, struct addrinfo *hint)
689258
+{
689258
+  /* Struct to hold the association between valid prefixes, their
689258
+     family and socktype.  */
689258
+  struct host_prefix
689258
+    {
689258
+      /* The prefix.  */
689258
+      const char *prefix;
689258
+
689258
+      /* The 'ai_family'.  */
689258
+      int family;
689258
+
689258
+      /* The 'ai_socktype'.  */
689258
+      int socktype;
689258
+    };
689258
+  static const struct host_prefix prefixes[] =
689258
+    {
689258
+      { "udp:",  AF_UNSPEC, SOCK_DGRAM },
689258
+      { "tcp:",  AF_UNSPEC, SOCK_STREAM },
689258
+      { "udp4:", AF_INET,   SOCK_DGRAM },
689258
+      { "tcp4:", AF_INET,   SOCK_STREAM },
689258
+      { "udp6:", AF_INET6,  SOCK_DGRAM },
689258
+      { "tcp6:", AF_INET6,  SOCK_STREAM },
689258
+    };
689258
+
689258
+  for (const host_prefix prefix : prefixes)
689258
+    if (startswith (spec, prefix.prefix))
689258
+      {
689258
+	spec += strlen (prefix.prefix);
689258
+	hint->ai_family = prefix.family;
689258
+	hint->ai_socktype = prefix.socktype;
689258
+	hint->ai_protocol
689258
+	  = hint->ai_socktype == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
689258
+	break;
689258
+      }
689258
+
689258
+  return parse_connection_spec_without_prefix (spec, hint);
689258
+}
689258
diff --git a/gdb/common/netstuff.h b/gdb/common/netstuff.h
689258
new file mode 100644
689258
--- /dev/null
689258
+++ b/gdb/common/netstuff.h
689258
@@ -0,0 +1,76 @@
689258
+/* Operations on network stuff.
689258
+   Copyright (C) 2018 Free Software Foundation, Inc.
689258
+
689258
+   This file is part of GDB.
689258
+
689258
+   This program is free software; you can redistribute it and/or modify
689258
+   it under the terms of the GNU General Public License as published by
689258
+   the Free Software Foundation; either version 3 of the License, or
689258
+   (at your option) any later version.
689258
+
689258
+   This program is distributed in the hope that it will be useful,
689258
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
689258
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
689258
+   GNU General Public License for more details.
689258
+
689258
+   You should have received a copy of the GNU General Public License
689258
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
689258
+
689258
+#ifndef NETSTUFF_H
689258
+#define NETSTUFF_H
689258
+
689258
+#include <string>
689258
+
689258
+/* Like NI_MAXHOST/NI_MAXSERV, but enough for numeric forms.  */
689258
+#define GDB_NI_MAX_ADDR 64
689258
+#define GDB_NI_MAX_PORT 16
689258
+
689258
+/* Helper class to guarantee that we always call 'freeaddrinfo'.  */
689258
+
689258
+class scoped_free_addrinfo
689258
+{
689258
+public:
689258
+  /* Default constructor.  */
689258
+  explicit scoped_free_addrinfo (struct addrinfo *ainfo)
689258
+    : m_res (ainfo)
689258
+  {
689258
+  }
689258
+
689258
+  /* Destructor responsible for free'ing M_RES by calling
689258
+     'freeaddrinfo'.  */
689258
+  ~scoped_free_addrinfo ();
689258
+
689258
+  DISABLE_COPY_AND_ASSIGN (scoped_free_addrinfo);
689258
+
689258
+private:
689258
+  /* The addrinfo resource.  */
689258
+  struct addrinfo *m_res;
689258
+};
689258
+
689258
+/* The struct we return after parsing the connection spec.  */
689258
+
689258
+struct parsed_connection_spec
689258
+{
689258
+  /* The hostname.  */
689258
+  std::string host_str;
689258
+
689258
+  /* The port, if any.  */
689258
+  std::string port_str;
689258
+};
689258
+
689258
+
689258
+/* Parse SPEC (which is a string in the form of "ADDR:PORT") and
689258
+   return a 'parsed_connection_spec' structure with the proper fields
689258
+   filled in.  Also adjust HINT accordingly.  */
689258
+extern parsed_connection_spec
689258
+  parse_connection_spec_without_prefix (std::string spec,
689258
+					struct addrinfo *hint);
689258
+
689258
+/* Parse SPEC (which is a string in the form of
689258
+   "[tcp[6]:|udp[6]:]ADDR:PORT") and return a 'parsed_connection_spec'
689258
+   structure with the proper fields filled in.  Also adjust HINT
689258
+   accordingly.  */
689258
+extern parsed_connection_spec parse_connection_spec (const char *spec,
689258
+						     struct addrinfo *hint);
689258
+
689258
+#endif /* ! NETSTUFF_H */
689258
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
689258
--- a/gdb/doc/ChangeLog
689258
+++ b/gdb/doc/ChangeLog
689258
@@ -1,3 +1,11 @@
689258
+2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>
689258
+	    Jan Kratochvil  <jan.kratochvil@redhat.com>
689258
+	    Paul Fertser  <fercerpav@gmail.com>
689258
+	    Tsutomu Seki  <sekiriki@gmail.com>
689258
+
689258
+	* gdb.texinfo (Remote Connection Commands): Add explanation
689258
+	about new IPv6 support.  Add new connection prefixes.
689258
+
689258
 2018-08-21  Alan Hayward  <alan.hayward@arm.com>
689258
 
689258
 	* gdb.texinfo (AArch64 SVE): New subsubsection.
689258
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
689258
--- a/gdb/doc/gdb.texinfo
689258
+++ b/gdb/doc/gdb.texinfo
689258
@@ -20548,16 +20548,27 @@ If you're using a serial line, you may want to give @value{GDBN} the
689258
 @code{target} command.
689258
 
689258
 @item target remote @code{@var{host}:@var{port}}
689258
+@itemx target remote @code{@var{[host]}:@var{port}}
689258
 @itemx target remote @code{tcp:@var{host}:@var{port}}
689258
+@itemx target remote @code{tcp:@var{[host]}:@var{port}}
689258
+@itemx target remote @code{tcp4:@var{host}:@var{port}}
689258
+@itemx target remote @code{tcp6:@var{host}:@var{port}}
689258
+@itemx target remote @code{tcp6:@var{[host]}:@var{port}}
689258
 @itemx target extended-remote @code{@var{host}:@var{port}}
689258
+@itemx target extended-remote @code{@var{[host]}:@var{port}}
689258
 @itemx target extended-remote @code{tcp:@var{host}:@var{port}}
689258
+@itemx target extended-remote @code{tcp:@var{[host]}:@var{port}}
689258
+@itemx target extended-remote @code{tcp4:@var{host}:@var{port}}
689258
+@itemx target extended-remote @code{tcp6:@var{host}:@var{port}}
689258
+@itemx target extended-remote @code{tcp6:@var{[host]}:@var{port}}
689258
 @cindex @acronym{TCP} port, @code{target remote}
689258
 Debug using a @acronym{TCP} connection to @var{port} on @var{host}.
689258
-The @var{host} may be either a host name or a numeric @acronym{IP}
689258
-address; @var{port} must be a decimal number.  The @var{host} could be
689258
-the target machine itself, if it is directly connected to the net, or
689258
-it might be a terminal server which in turn has a serial line to the
689258
-target.
689258
+The @var{host} may be either a host name, a numeric @acronym{IPv4}
689258
+address, or a numeric @acronym{IPv6} address (with or without the
689258
+square brackets to separate the address from the port); @var{port}
689258
+must be a decimal number.  The @var{host} could be the target machine
689258
+itself, if it is directly connected to the net, or it might be a
689258
+terminal server which in turn has a serial line to the target.
689258
 
689258
 For example, to connect to port 2828 on a terminal server named
689258
 @code{manyfarms}:
689258
@@ -20566,6 +20577,28 @@ For example, to connect to port 2828 on a terminal server named
689258
 target remote manyfarms:2828
689258
 @end smallexample
689258
 
689258
+To connect to port 2828 on a terminal server whose address is
689258
+@code{2001:0db8:85a3:0000:0000:8a2e:0370:7334}, you can either use the
689258
+square bracket syntax:
689258
+
689258
+@smallexample
689258
+target remote [2001:0db8:85a3:0000:0000:8a2e:0370:7334]:2828
689258
+@end smallexample
689258
+
689258
+@noindent
689258
+or explicitly specify the @acronym{IPv6} protocol:
689258
+
689258
+@smallexample
689258
+target remote tcp6:2001:0db8:85a3:0000:0000:8a2e:0370:7334:2828
689258
+@end smallexample
689258
+
689258
+This last example may be confusing to the reader, because there is no
689258
+visible separation between the hostname and the port number.
689258
+Therefore, we recommend the user to provide @acronym{IPv6} addresses
689258
+using square brackets for clarity.  However, it is important to
689258
+mention that for @value{GDBN} there is no ambiguity: the number after
689258
+the last colon is considered to be the port number.
689258
+
689258
 If your remote target is actually running on the same machine as your
689258
 debugger session (e.g.@: a simulator for your target running on the
689258
 same host), you can omit the hostname.  For example, to connect to
689258
@@ -20579,7 +20612,15 @@ target remote :1234
689258
 Note that the colon is still required here.
689258
 
689258
 @item target remote @code{udp:@var{host}:@var{port}}
689258
+@itemx target remote @code{udp:@var{[host]}:@var{port}}
689258
+@itemx target remote @code{udp4:@var{host}:@var{port}}
689258
+@itemx target remote @code{udp6:@var{[host]}:@var{port}}
689258
+@itemx target extended-remote @code{udp:@var{host}:@var{port}}
689258
 @itemx target extended-remote @code{udp:@var{host}:@var{port}}
689258
+@itemx target extended-remote @code{udp:@var{[host]}:@var{port}}
689258
+@itemx target extended-remote @code{udp4:@var{host}:@var{port}}
689258
+@itemx target extended-remote @code{udp6:@var{host}:@var{port}}
689258
+@itemx target extended-remote @code{udp6:@var{[host]}:@var{port}}
689258
 @cindex @acronym{UDP} port, @code{target remote}
689258
 Debug using @acronym{UDP} packets to @var{port} on @var{host}.  For example, to
689258
 connect to @acronym{UDP} port 2828 on a terminal server named @code{manyfarms}:
689258
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
689258
--- a/gdb/gdbserver/ChangeLog
689258
+++ b/gdb/gdbserver/ChangeLog
689258
@@ -1,3 +1,22 @@
689258
+2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>
689258
+	    Jan Kratochvil  <jan.kratochvil@redhat.com>
689258
+	    Paul Fertser  <fercerpav@gmail.com>
689258
+	    Tsutomu Seki  <sekiriki@gmail.com>
689258
+
689258
+	* Makefile.in (SFILES): Add '$(srcdir)/common/netstuff.c'.
689258
+	(OBS): Add 'common/netstuff.o'.
689258
+	(GDBREPLAY_OBS): Likewise.
689258
+	* gdbreplay.c: Include 'wspiapi.h' and 'netstuff.h'.
689258
+	(remote_open): Implement support for IPv6
689258
+	connections.
689258
+	* remote-utils.c: Include 'netstuff.h', 'filestuff.h'
689258
+	and 'wspiapi.h'.
689258
+	(handle_accept_event): Accept connections from IPv6 sources.
689258
+	(remote_prepare): Handle IPv6-style hostnames; implement
689258
+	support for IPv6 connections.
689258
+	(remote_open): Implement support for printing connections from
689258
+	IPv6 sources.
689258
+
689258
 2018-08-26  Simon Marchi  <simon.marchi@ericsson.com>
689258
 
689258
 	PR gdb/23374
689258
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
689258
--- a/gdb/gdbserver/Makefile.in
689258
+++ b/gdb/gdbserver/Makefile.in
689258
@@ -211,6 +211,7 @@ SFILES = \
689258
 	$(srcdir)/common/job-control.c \
689258
 	$(srcdir)/common/gdb_tilde_expand.c \
689258
 	$(srcdir)/common/gdb_vecs.c \
689258
+	$(srcdir)/common/netstuff.c \
689258
 	$(srcdir)/common/new-op.c \
689258
 	$(srcdir)/common/pathstuff.c \
689258
 	$(srcdir)/common/print-utils.c \
689258
@@ -254,6 +255,7 @@ OBS = \
689258
 	common/format.o \
689258
 	common/gdb_tilde_expand.o \
689258
 	common/gdb_vecs.o \
689258
+	common/netstuff.o \
689258
 	common/new-op.o \
689258
 	common/pathstuff.o \
689258
 	common/print-utils.o \
689258
@@ -290,6 +292,7 @@ GDBREPLAY_OBS = \
689258
 	common/common-exceptions.o \
689258
 	common/common-utils.o \
689258
 	common/errors.o \
689258
+	common/netstuff.o \
689258
 	common/print-utils.o \
689258
 	gdbreplay.o \
689258
 	utils.o \
689258
diff --git a/gdb/gdbserver/gdbreplay.c b/gdb/gdbserver/gdbreplay.c
689258
--- a/gdb/gdbserver/gdbreplay.c
689258
+++ b/gdb/gdbserver/gdbreplay.c
689258
@@ -46,8 +46,11 @@
689258
 
689258
 #if USE_WIN32API
689258
 #include <winsock2.h>
689258
+#include <wspiapi.h>
689258
 #endif
689258
 
689258
+#include "netstuff.h"
689258
+
689258
 #ifndef HAVE_SOCKLEN_T
689258
 typedef int socklen_t;
689258
 #endif
689258
@@ -142,56 +145,108 @@ remote_close (void)
689258
 static void
689258
 remote_open (char *name)
689258
 {
689258
-  if (!strchr (name, ':'))
689258
+  char *last_colon = strrchr (name, ':');
689258
+
689258
+  if (last_colon == NULL)
689258
     {
689258
       fprintf (stderr, "%s: Must specify tcp connection as host:addr\n", name);
689258
       fflush (stderr);
689258
       exit (1);
689258
     }
689258
-  else
689258
-    {
689258
+
689258
 #ifdef USE_WIN32API
689258
-      static int winsock_initialized;
689258
+  static int winsock_initialized;
689258
 #endif
689258
-      char *port_str;
689258
-      int port;
689258
-      struct sockaddr_in sockaddr;
689258
-      socklen_t tmp;
689258
-      int tmp_desc;
689258
+  char *port_str;
689258
+  int tmp;
689258
+  int tmp_desc;
689258
+  struct addrinfo hint;
689258
+  struct addrinfo *ainfo;
689258
 
689258
-      port_str = strchr (name, ':');
689258
+  memset (&hint, 0, sizeof (hint));
689258
+  /* Assume no prefix will be passed, therefore we should use
689258
+     AF_UNSPEC.  */
689258
+  hint.ai_family = AF_UNSPEC;
689258
+  hint.ai_socktype = SOCK_STREAM;
689258
+  hint.ai_protocol = IPPROTO_TCP;
689258
 
689258
-      port = atoi (port_str + 1);
689258
+  parsed_connection_spec parsed = parse_connection_spec (name, &hint);
689258
+
689258
+  if (parsed.port_str.empty ())
689258
+    error (_("Missing port on hostname '%s'"), name);
689258
 
689258
 #ifdef USE_WIN32API
689258
-      if (!winsock_initialized)
689258
-	{
689258
-	  WSADATA wsad;
689258
+  if (!winsock_initialized)
689258
+    {
689258
+      WSADATA wsad;
689258
 
689258
-	  WSAStartup (MAKEWORD (1, 0), &wsad);
689258
-	  winsock_initialized = 1;
689258
-	}
689258
+      WSAStartup (MAKEWORD (1, 0), &wsad);
689258
+      winsock_initialized = 1;
689258
+    }
689258
 #endif
689258
 
689258
-      tmp_desc = socket (PF_INET, SOCK_STREAM, 0);
689258
-      if (tmp_desc == -1)
689258
-	perror_with_name ("Can't open socket");
689258
+  int r = getaddrinfo (parsed.host_str.c_str (), parsed.port_str.c_str (),
689258
+		       &hint, &ainfo);
689258
 
689258
-      /* Allow rapid reuse of this port. */
689258
-      tmp = 1;
689258
-      setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
689258
-		  sizeof (tmp));
689258
+  if (r != 0)
689258
+    {
689258
+      fprintf (stderr, "%s:%s: cannot resolve name: %s\n",
689258
+	       parsed.host_str.c_str (), parsed.port_str.c_str (),
689258
+	       gai_strerror (r));
689258
+      fflush (stderr);
689258
+      exit (1);
689258
+    }
689258
+
689258
+  scoped_free_addrinfo free_ainfo (ainfo);
689258
+
689258
+  struct addrinfo *p;
689258
+
689258
+  for (p = ainfo; p != NULL; p = p->ai_next)
689258
+    {
689258
+      tmp_desc = socket (p->ai_family, p->ai_socktype, p->ai_protocol);
689258
 
689258
-      sockaddr.sin_family = PF_INET;
689258
-      sockaddr.sin_port = htons (port);
689258
-      sockaddr.sin_addr.s_addr = INADDR_ANY;
689258
+      if (tmp_desc >= 0)
689258
+	break;
689258
+    }
689258
+
689258
+  if (p == NULL)
689258
+    perror_with_name ("Cannot open socket");
689258
 
689258
-      if (bind (tmp_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
689258
-	  || listen (tmp_desc, 1))
689258
-	perror_with_name ("Can't bind address");
689258
+  /* Allow rapid reuse of this port. */
689258
+  tmp = 1;
689258
+  setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
689258
+	      sizeof (tmp));
689258
+
689258
+  switch (p->ai_family)
689258
+    {
689258
+    case AF_INET:
689258
+      ((struct sockaddr_in *) p->ai_addr)->sin_addr.s_addr = INADDR_ANY;
689258
+      break;
689258
+    case AF_INET6:
689258
+      ((struct sockaddr_in6 *) p->ai_addr)->sin6_addr = in6addr_any;
689258
+      break;
689258
+    default:
689258
+      fprintf (stderr, "Invalid 'ai_family' %d\n", p->ai_family);
689258
+      exit (1);
689258
+    }
689258
+
689258
+  if (bind (tmp_desc, p->ai_addr, p->ai_addrlen) != 0)
689258
+    perror_with_name ("Can't bind address");
689258
+
689258
+  if (p->ai_socktype == SOCK_DGRAM)
689258
+    remote_desc = tmp_desc;
689258
+  else
689258
+    {
689258
+      struct sockaddr_storage sockaddr;
689258
+      socklen_t sockaddrsize = sizeof (sockaddr);
689258
+      char orig_host[GDB_NI_MAX_ADDR], orig_port[GDB_NI_MAX_PORT];
689258
+
689258
+      if (listen (tmp_desc, 1) != 0)
689258
+	perror_with_name ("Can't listen on socket");
689258
+
689258
+      remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr,
689258
+			    &sockaddrsize);
689258
 
689258
-      tmp = sizeof (sockaddr);
689258
-      remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp);
689258
       if (remote_desc == -1)
689258
 	perror_with_name ("Accept failed");
689258
 
689258
@@ -206,6 +261,16 @@ remote_open (char *name)
689258
       setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
689258
 		  (char *) &tmp, sizeof (tmp));
689258
 
689258
+      if (getnameinfo ((struct sockaddr *) &sockaddr, sockaddrsize,
689258
+		       orig_host, sizeof (orig_host),
689258
+		       orig_port, sizeof (orig_port),
689258
+		       NI_NUMERICHOST | NI_NUMERICSERV) == 0)
689258
+	{
689258
+	  fprintf (stderr, "Remote debugging from host %s, port %s\n",
689258
+		   orig_host, orig_port);
689258
+	  fflush (stderr);
689258
+	}
689258
+
689258
 #ifndef USE_WIN32API
689258
       close (tmp_desc);		/* No longer need this */
689258
 
689258
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
689258
--- a/gdb/gdbserver/remote-utils.c
689258
+++ b/gdb/gdbserver/remote-utils.c
689258
@@ -26,6 +26,8 @@
689258
 #include "dll.h"
689258
 #include "rsp-low.h"
689258
 #include "gdbthread.h"
689258
+#include "netstuff.h"
689258
+#include "filestuff.h"
689258
 #include <ctype.h>
689258
 #if HAVE_SYS_IOCTL_H
689258
 #include <sys/ioctl.h>
689258
@@ -63,6 +65,7 @@
689258
 
689258
 #if USE_WIN32API
689258
 #include <winsock2.h>
689258
+#include <wspiapi.h>
689258
 #endif
689258
 
689258
 #if __QNX__
689258
@@ -151,19 +154,18 @@ enable_async_notification (int fd)
689258
 static int
689258
 handle_accept_event (int err, gdb_client_data client_data)
689258
 {
689258
-  struct sockaddr_in sockaddr;
689258
-  socklen_t tmp;
689258
+  struct sockaddr_storage sockaddr;
689258
+  socklen_t len = sizeof (sockaddr);
689258
 
689258
   if (debug_threads)
689258
     debug_printf ("handling possible accept event\n");
689258
 
689258
-  tmp = sizeof (sockaddr);
689258
-  remote_desc = accept (listen_desc, (struct sockaddr *) &sockaddr, &tmp);
689258
+  remote_desc = accept (listen_desc, (struct sockaddr *) &sockaddr, &len;;
689258
   if (remote_desc == -1)
689258
     perror_with_name ("Accept failed");
689258
 
689258
   /* Enable TCP keep alive process. */
689258
-  tmp = 1;
689258
+  socklen_t tmp = 1;
689258
   setsockopt (remote_desc, SOL_SOCKET, SO_KEEPALIVE,
689258
 	      (char *) &tmp, sizeof (tmp));
689258
 
689258
@@ -192,8 +194,19 @@ handle_accept_event (int err, gdb_client_data client_data)
689258
   delete_file_handler (listen_desc);
689258
 
689258
   /* Convert IP address to string.  */
689258
-  fprintf (stderr, "Remote debugging from host %s\n",
689258
-	   inet_ntoa (sockaddr.sin_addr));
689258
+  char orig_host[GDB_NI_MAX_ADDR], orig_port[GDB_NI_MAX_PORT];
689258
+
689258
+  int r = getnameinfo ((struct sockaddr *) &sockaddr, len,
689258
+		       orig_host, sizeof (orig_host),
689258
+		       orig_port, sizeof (orig_port),
689258
+		       NI_NUMERICHOST | NI_NUMERICSERV);
689258
+
689258
+  if (r != 0)
689258
+    fprintf (stderr, _("Could not obtain remote address: %s\n"),
689258
+	     gai_strerror (r));
689258
+  else
689258
+    fprintf (stderr, _("Remote debugging from host %s, port %s\n"),
689258
+	     orig_host, orig_port);
689258
 
689258
   enable_async_notification (remote_desc);
689258
 
689258
@@ -222,10 +235,7 @@ remote_prepare (const char *name)
689258
 #ifdef USE_WIN32API
689258
   static int winsock_initialized;
689258
 #endif
689258
-  int port;
689258
-  struct sockaddr_in sockaddr;
689258
   socklen_t tmp;
689258
-  char *port_end;
689258
 
689258
   remote_is_stdio = 0;
689258
   if (strcmp (name, STDIO_CONNECTION_NAME) == 0)
689258
@@ -238,17 +248,25 @@ remote_prepare (const char *name)
689258
       return;
689258
     }
689258
 
689258
-  port_str = strchr (name, ':');
689258
-  if (port_str == NULL)
689258
+  struct addrinfo hint;
689258
+  struct addrinfo *ainfo;
689258
+
689258
+  memset (&hint, 0, sizeof (hint));
689258
+  /* Assume no prefix will be passed, therefore we should use
689258
+     AF_UNSPEC.  */
689258
+  hint.ai_family = AF_UNSPEC;
689258
+  hint.ai_socktype = SOCK_STREAM;
689258
+  hint.ai_protocol = IPPROTO_TCP;
689258
+
689258
+  parsed_connection_spec parsed
689258
+    = parse_connection_spec_without_prefix (name, &hint);
689258
+
689258
+  if (parsed.port_str.empty ())
689258
     {
689258
       cs.transport_is_reliable = 0;
689258
       return;
689258
     }
689258
 
689258
-  port = strtoul (port_str + 1, &port_end, 10);
689258
-  if (port_str[1] == '\0' || *port_end != '\0')
689258
-    error ("Bad port argument: %s", name);
689258
-
689258
 #ifdef USE_WIN32API
689258
   if (!winsock_initialized)
689258
     {
689258
@@ -259,8 +277,26 @@ remote_prepare (const char *name)
689258
     }
689258
 #endif
689258
 
689258
-  listen_desc = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
689258
-  if (listen_desc == -1)
689258
+  int r = getaddrinfo (parsed.host_str.c_str (), parsed.port_str.c_str (),
689258
+		       &hint, &ainfo);
689258
+
689258
+  if (r != 0)
689258
+    error (_("%s: cannot resolve name: %s"), name, gai_strerror (r));
689258
+
689258
+  scoped_free_addrinfo freeaddrinfo (ainfo);
689258
+
689258
+  struct addrinfo *iter;
689258
+
689258
+  for (iter = ainfo; iter != NULL; iter = iter->ai_next)
689258
+    {
689258
+      listen_desc = gdb_socket_cloexec (iter->ai_family, iter->ai_socktype,
689258
+					iter->ai_protocol);
689258
+
689258
+      if (listen_desc >= 0)
689258
+	break;
689258
+    }
689258
+
689258
+  if (iter == NULL)
689258
     perror_with_name ("Can't open socket");
689258
 
689258
   /* Allow rapid reuse of this port. */
689258
@@ -268,14 +304,25 @@ remote_prepare (const char *name)
689258
   setsockopt (listen_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
689258
 	      sizeof (tmp));
689258
 
689258
-  sockaddr.sin_family = PF_INET;
689258
-  sockaddr.sin_port = htons (port);
689258
-  sockaddr.sin_addr.s_addr = INADDR_ANY;
689258
+  switch (iter->ai_family)
689258
+    {
689258
+    case AF_INET:
689258
+      ((struct sockaddr_in *) iter->ai_addr)->sin_addr.s_addr = INADDR_ANY;
689258
+      break;
689258
+    case AF_INET6:
689258
+      ((struct sockaddr_in6 *) iter->ai_addr)->sin6_addr = in6addr_any;
689258
+      break;
689258
+    default:
689258
+      internal_error (__FILE__, __LINE__,
689258
+		      _("Invalid 'ai_family' %d\n"), iter->ai_family);
689258
+    }
689258
 
689258
-  if (bind (listen_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
689258
-      || listen (listen_desc, 1))
689258
+  if (bind (listen_desc, iter->ai_addr, iter->ai_addrlen) != 0)
689258
     perror_with_name ("Can't bind address");
689258
 
689258
+  if (listen (listen_desc, 1) != 0)
689258
+    perror_with_name ("Can't listen on socket");
689258
+
689258
   cs.transport_is_reliable = 1;
689258
 }
689258
 
689258
@@ -350,18 +397,24 @@ remote_open (const char *name)
689258
 #endif /* USE_WIN32API */
689258
   else
689258
     {
689258
-      int port;
689258
-      socklen_t len;
689258
-      struct sockaddr_in sockaddr;
689258
-
689258
-      len = sizeof (sockaddr);
689258
-      if (getsockname (listen_desc,
689258
-		       (struct sockaddr *) &sockaddr, &len) < 0
689258
-	  || len < sizeof (sockaddr))
689258
+      char listen_port[GDB_NI_MAX_PORT];
689258
+      struct sockaddr_storage sockaddr;
689258
+      socklen_t len = sizeof (sockaddr);
689258
+
689258
+      if (getsockname (listen_desc, (struct sockaddr *) &sockaddr, &len) < 0)
689258
 	perror_with_name ("Can't determine port");
689258
-      port = ntohs (sockaddr.sin_port);
689258
 
689258
-      fprintf (stderr, "Listening on port %d\n", port);
689258
+      int r = getnameinfo ((struct sockaddr *) &sockaddr, len,
689258
+			   NULL, 0,
689258
+			   listen_port, sizeof (listen_port),
689258
+			   NI_NUMERICSERV);
689258
+
689258
+      if (r != 0)
689258
+	fprintf (stderr, _("Can't obtain port where we are listening: %s"),
689258
+		 gai_strerror (r));
689258
+      else
689258
+	fprintf (stderr, _("Listening on port %s\n"), listen_port);
689258
+
689258
       fflush (stderr);
689258
 
689258
       /* Register the event loop handler.  */
689258
diff --git a/gdb/ser-tcp.c b/gdb/ser-tcp.c
689258
--- a/gdb/ser-tcp.c
689258
+++ b/gdb/ser-tcp.c
689258
@@ -25,6 +25,7 @@
689258
 #include "cli/cli-decode.h"
689258
 #include "cli/cli-setshow.h"
689258
 #include "filestuff.h"
689258
+#include "netstuff.h"
689258
 
689258
 #include <sys/types.h>
689258
 
689258
@@ -39,6 +40,7 @@
689258
 
689258
 #ifdef USE_WIN32API
689258
 #include <winsock2.h>
689258
+#include <wspiapi.h>
689258
 #ifndef ETIMEDOUT
689258
 #define ETIMEDOUT WSAETIMEDOUT
689258
 #endif
689258
@@ -81,12 +83,13 @@ static unsigned int tcp_retry_limit = 15;
689258
 
689258
 #define POLL_INTERVAL 5
689258
 
689258
-/* Helper function to wait a while.  If SCB is non-null, wait on its
689258
-   file descriptor.  Otherwise just wait on a timeout, updating *POLLS.
689258
-   Returns -1 on timeout or interrupt, otherwise the value of select.  */
689258
+/* Helper function to wait a while.  If SOCK is not -1, wait on its
689258
+   file descriptor.  Otherwise just wait on a timeout, updating
689258
+   *POLLS.  Returns -1 on timeout or interrupt, otherwise the value of
689258
+   select.  */
689258
 
689258
 static int
689258
-wait_for_connect (struct serial *scb, unsigned int *polls)
689258
+wait_for_connect (int sock, unsigned int *polls)
689258
 {
689258
   struct timeval t;
689258
   int n;
689258
@@ -120,24 +123,24 @@ wait_for_connect (struct serial *scb, unsigned int *polls)
689258
       t.tv_usec = 0;
689258
     }
689258
 
689258
-  if (scb)
689258
+  if (sock >= 0)
689258
     {
689258
       fd_set rset, wset, eset;
689258
 
689258
       FD_ZERO (&rset);
689258
-      FD_SET (scb->fd, &rset);
689258
+      FD_SET (sock, &rset);
689258
       wset = rset;
689258
       eset = rset;
689258
-	  
689258
+
689258
       /* POSIX systems return connection success or failure by signalling
689258
 	 wset.  Windows systems return success in wset and failure in
689258
 	 eset.
689258
-     
689258
+
689258
 	 We must call select here, rather than gdb_select, because
689258
 	 the serial structure has not yet been initialized - the
689258
 	 MinGW select wrapper will not know that this FD refers
689258
 	 to a socket.  */
689258
-      n = select (scb->fd + 1, &rset, &wset, &eset, &t);
689258
+      n = select (sock + 1, &rset, &wset, &eset, &t);
689258
     }
689258
   else
689258
     /* Use gdb_select here, since we have no file descriptors, and on
689258
@@ -153,80 +156,28 @@ wait_for_connect (struct serial *scb, unsigned int *polls)
689258
   return n;
689258
 }
689258
 
689258
-/* Open a tcp socket.  */
689258
+/* Try to connect to the host represented by AINFO.  If the connection
689258
+   succeeds, return its socket.  Otherwise, return -1 and set ERRNO
689258
+   accordingly.  POLLS is used when 'connect' returns EINPROGRESS, and
689258
+   we need to invoke 'wait_for_connect' to obtain the status.  */
689258
 
689258
-int
689258
-net_open (struct serial *scb, const char *name)
689258
+static int
689258
+try_connect (const struct addrinfo *ainfo, unsigned int *polls)
689258
 {
689258
-  char hostname[100];
689258
-  const char *port_str;
689258
-  int n, port, tmp;
689258
-  int use_udp;
689258
-  struct hostent *hostent;
689258
-  struct sockaddr_in sockaddr;
689258
-#ifdef USE_WIN32API
689258
-  u_long ioarg;
689258
-#else
689258
-  int ioarg;
689258
-#endif
689258
-  unsigned int polls = 0;
689258
-
689258
-  use_udp = 0;
689258
-  if (startswith (name, "udp:"))
689258
-    {
689258
-      use_udp = 1;
689258
-      name = name + 4;
689258
-    }
689258
-  else if (startswith (name, "tcp:"))
689258
-    name = name + 4;
689258
-
689258
-  port_str = strchr (name, ':');
689258
-
689258
-  if (!port_str)
689258
-    error (_("net_open: No colon in host name!"));  /* Shouldn't ever
689258
-						       happen.  */
689258
-
689258
-  tmp = std::min (port_str - name, (ptrdiff_t) sizeof hostname - 1);
689258
-  strncpy (hostname, name, tmp);	/* Don't want colon.  */
689258
-  hostname[tmp] = '\000';	/* Tie off host name.  */
689258
-  port = atoi (port_str + 1);
689258
-
689258
-  /* Default hostname is localhost.  */
689258
-  if (!hostname[0])
689258
-    strcpy (hostname, "localhost");
689258
-
689258
-  hostent = gethostbyname (hostname);
689258
-  if (!hostent)
689258
-    {
689258
-      fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
689258
-      errno = ENOENT;
689258
-      return -1;
689258
-    }
689258
+  int sock = gdb_socket_cloexec (ainfo->ai_family, ainfo->ai_socktype,
689258
+				 ainfo->ai_protocol);
689258
 
689258
-  sockaddr.sin_family = PF_INET;
689258
-  sockaddr.sin_port = htons (port);
689258
-  memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
689258
-	  sizeof (struct in_addr));
689258
-
689258
- retry:
689258
-
689258
-  if (use_udp)
689258
-    scb->fd = gdb_socket_cloexec (PF_INET, SOCK_DGRAM, 0);
689258
-  else
689258
-    scb->fd = gdb_socket_cloexec (PF_INET, SOCK_STREAM, 0);
689258
-
689258
-  if (scb->fd == -1)
689258
+  if (sock < 0)
689258
     return -1;
689258
-  
689258
+
689258
   /* Set socket nonblocking.  */
689258
-  ioarg = 1;
689258
-  ioctl (scb->fd, FIONBIO, &ioarg);
689258
+  int ioarg = 1;
689258
+
689258
+  ioctl (sock, FIONBIO, &ioarg);
689258
 
689258
   /* Use Non-blocking connect.  connect() will return 0 if connected
689258
      already.  */
689258
-  n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
689258
-
689258
-  if (n < 0)
689258
+  if (connect (sock, ainfo->ai_addr, ainfo->ai_addrlen) < 0)
689258
     {
689258
 #ifdef USE_WIN32API
689258
       int err = WSAGetLastError();
689258
@@ -234,21 +185,26 @@ net_open (struct serial *scb, const char *name)
689258
       int err = errno;
689258
 #endif
689258
 
689258
-      /* Maybe we're waiting for the remote target to become ready to
689258
-	 accept connections.  */
689258
-      if (tcp_auto_retry
689258
+      /* If we've got a "connection refused" error, just return
689258
+	 -1.  The caller will know what to do.  */
689258
+      if (
689258
 #ifdef USE_WIN32API
689258
-	  && err == WSAECONNREFUSED
689258
+	  err == WSAECONNREFUSED
689258
 #else
689258
-	  && err == ECONNREFUSED
689258
+	  err == ECONNREFUSED
689258
 #endif
689258
-	  && wait_for_connect (NULL, &polls) >= 0)
689258
+	  )
689258
 	{
689258
-	  close (scb->fd);
689258
-	  goto retry;
689258
+	  close (sock);
689258
+	  errno = err;
689258
+	  return -1;
689258
 	}
689258
 
689258
       if (
689258
+	  /* Any other error (except EINPROGRESS) will be "swallowed"
689258
+	     here.  We return without specifying a return value, and
689258
+	     set errno if the caller wants to inspect what
689258
+	     happened.  */
689258
 #ifdef USE_WIN32API
689258
 	  /* Under Windows, calling "connect" with a non-blocking socket
689258
 	     results in WSAEWOULDBLOCK, not WSAEINPROGRESS.  */
689258
@@ -258,66 +214,166 @@ net_open (struct serial *scb, const char *name)
689258
 #endif
689258
 	  )
689258
 	{
689258
+	  close (sock);
689258
 	  errno = err;
689258
-	  net_close (scb);
689258
 	  return -1;
689258
 	}
689258
 
689258
       /* Looks like we need to wait for the connect.  */
689258
-      do 
689258
-	{
689258
-	  n = wait_for_connect (scb, &polls);
689258
-	} 
689258
+      int n;
689258
+
689258
+      do
689258
+	n = wait_for_connect (sock, polls);
689258
       while (n == 0);
689258
+
689258
       if (n < 0)
689258
 	{
689258
-	  net_close (scb);
689258
+	  int saved_errno = errno;
689258
+
689258
+	  /* A negative value here means that we either timed out or
689258
+	     got interrupted by the user.  Just return.  */
689258
+	  close (sock);
689258
+	  errno = saved_errno;
689258
 	  return -1;
689258
 	}
689258
     }
689258
 
689258
   /* Got something.  Is it an error?  */
689258
-  {
689258
-    int res, err;
689258
-    socklen_t len;
689258
-
689258
-    len = sizeof (err);
689258
-    /* On Windows, the fourth parameter to getsockopt is a "char *";
689258
-       on UNIX systems it is generally "void *".  The cast to "char *"
689258
-       is OK everywhere, since in C++ any data pointer type can be
689258
-       implicitly converted to "void *".  */
689258
-    res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, (char *) &err, &len;;
689258
-    if (res < 0 || err)
689258
-      {
689258
-	/* Maybe the target still isn't ready to accept the connection.  */
689258
-	if (tcp_auto_retry
689258
+  int err;
689258
+  socklen_t len = sizeof (err);
689258
+
689258
+  /* On Windows, the fourth parameter to getsockopt is a "char *";
689258
+     on UNIX systems it is generally "void *".  The cast to "char *"
689258
+     is OK everywhere, since in C++ any data pointer type can be
689258
+     implicitly converted to "void *".  */
689258
+  int ret = getsockopt (sock, SOL_SOCKET, SO_ERROR, (char *) &err, &len;;
689258
+
689258
+  if (ret < 0)
689258
+    {
689258
+      int saved_errno = errno;
689258
+
689258
+      close (sock);
689258
+      errno = saved_errno;
689258
+      return -1;
689258
+    }
689258
+  else if (ret == 0 && err != 0)
689258
+    {
689258
+      close (sock);
689258
+      errno = err;
689258
+      return -1;
689258
+    }
689258
+
689258
+  /* The connection succeeded.  Return the socket.  */
689258
+  return sock;
689258
+}
689258
+
689258
+/* Open a tcp socket.  */
689258
+
689258
+int
689258
+net_open (struct serial *scb, const char *name)
689258
+{
689258
+  struct addrinfo hint;
689258
+  struct addrinfo *ainfo;
689258
+
689258
+  memset (&hint, 0, sizeof (hint));
689258
+  /* Assume no prefix will be passed, therefore we should use
689258
+     AF_UNSPEC.  */
689258
+  hint.ai_family = AF_UNSPEC;
689258
+  hint.ai_socktype = SOCK_STREAM;
689258
+  hint.ai_protocol = IPPROTO_TCP;
689258
+
689258
+  parsed_connection_spec parsed = parse_connection_spec (name, &hint);
689258
+
689258
+  if (parsed.port_str.empty ())
689258
+    error (_("Missing port on hostname '%s'"), name);
689258
+
689258
+  int r = getaddrinfo (parsed.host_str.c_str (),
689258
+		       parsed.port_str.c_str (),
689258
+		       &hint, &ainfo);
689258
+
689258
+  if (r != 0)
689258
+    {
689258
+      fprintf_unfiltered (gdb_stderr, _("%s: cannot resolve name: %s\n"),
689258
+			  name, gai_strerror (r));
689258
+      errno = ENOENT;
689258
+      return -1;
689258
+    }
689258
+
689258
+  scoped_free_addrinfo free_ainfo (ainfo);
689258
+
689258
+  /* Flag to indicate whether we've got a connection refused.  It will
689258
+     be true if any of the connections tried was refused.  */
689258
+  bool got_connrefused;
689258
+  /* If a connection succeeeds, SUCCESS_AINFO will point to the
689258
+     'struct addrinfo' that succeed.  */
689258
+  struct addrinfo *success_ainfo = NULL;
689258
+  unsigned int polls = 0;
689258
+
689258
+  /* Assume the worst.  */
689258
+  scb->fd = -1;
689258
+
689258
+  do
689258
+    {
689258
+      got_connrefused = false;
689258
+
689258
+      for (struct addrinfo *iter = ainfo; iter != NULL; iter = iter->ai_next)
689258
+	{
689258
+	  /* Iterate over the list of possible addresses to connect
689258
+	     to.  For each, we'll try to connect and see if it
689258
+	     succeeds.  */
689258
+	  int sock = try_connect (iter, &polls);
689258
+
689258
+	  if (sock >= 0)
689258
+	    {
689258
+	      /* We've gotten a successful connection.  Save its
689258
+		 'struct addrinfo', the socket, and break.  */
689258
+	      success_ainfo = iter;
689258
+	      scb->fd = sock;
689258
+	      break;
689258
+	    }
689258
+	  else if (
689258
 #ifdef USE_WIN32API
689258
-	    && err == WSAECONNREFUSED
689258
+	  errno == WSAECONNREFUSED
689258
 #else
689258
-	    && err == ECONNREFUSED
689258
+	  errno == ECONNREFUSED
689258
 #endif
689258
-	    && wait_for_connect (NULL, &polls) >= 0)
689258
-	  {
689258
-	    close (scb->fd);
689258
-	    goto retry;
689258
-	  }
689258
-	if (err)
689258
-	  errno = err;
689258
-	net_close (scb);
689258
-	return -1;
689258
-      }
689258
-  } 
689258
+		   )
689258
+	    got_connrefused = true;
689258
+	}
689258
+    }
689258
+  /* Just retry if:
689258
+
689258
+     - tcp_auto_retry is true, and
689258
+     - We haven't gotten a connection yet, and
689258
+     - Any of our connection attempts returned with ECONNREFUSED, and
689258
+     - wait_for_connect signals that we can keep going.  */
689258
+  while (tcp_auto_retry
689258
+	 && success_ainfo == NULL
689258
+	 && got_connrefused
689258
+	 && wait_for_connect (-1, &polls) >= 0);
689258
+
689258
+  if (success_ainfo == NULL)
689258
+    {
689258
+      net_close (scb);
689258
+      return -1;
689258
+    }
689258
 
689258
   /* Turn off nonblocking.  */
689258
-  ioarg = 0;
689258
+#ifdef USE_WIN32API
689258
+  u_long ioarg = 0;
689258
+#else
689258
+  int ioarg = 0;
689258
+#endif
689258
+
689258
   ioctl (scb->fd, FIONBIO, &ioarg);
689258
 
689258
-  if (use_udp == 0)
689258
+  if (success_ainfo->ai_socktype == IPPROTO_TCP)
689258
     {
689258
       /* Disable Nagle algorithm.  Needed in some cases.  */
689258
-      tmp = 1;
689258
+      int tmp = 1;
689258
+
689258
       setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY,
689258
-		  (char *)&tmp, sizeof (tmp));
689258
+		  (char *) &tmp, sizeof (tmp));
689258
     }
689258
 
689258
 #ifdef SIGPIPE
689258
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
689258
--- a/gdb/testsuite/ChangeLog
689258
+++ b/gdb/testsuite/ChangeLog
689258
@@ -1,3 +1,23 @@
689258
+2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>
689258
+	    Jan Kratochvil  <jan.kratochvil@redhat.com>
689258
+	    Paul Fertser  <fercerpav@gmail.com>
689258
+	    Tsutomu Seki  <sekiriki@gmail.com>
689258
+
689258
+	* README (Testsuite Parameters): Mention new 'GDB_TEST_SOCKETHOST'
689258
+	parameter.
689258
+	* boards/native-extended-gdbserver.exp: Do not set 'sockethost'
689258
+	by default.
689258
+	* boards/native-gdbserver.exp: Likewise.
689258
+	* gdb.server/run-without-local-binary.exp: Improve regexp used
689258
+	for detecting when a remote debugging connection succeeds.
689258
+	* gdb.server/server-connect.exp: New file.
689258
+	* lib/gdbserver-support.exp (gdbserver_default_get_comm_port):
689258
+	Do not prefix the port number with ":".
689258
+	(gdbserver_start): New global GDB_TEST_SOCKETHOST.  Implement
689258
+	support for detecting and using it.  Add '$debughost_gdbserver'
689258
+	to the list of arguments used to start gdbserver.  Handle case
689258
+	when gdbserver cannot resolve a network name.
689258
+
689258
 2018-08-31  Tom Tromey  <tom@tromey.com>
689258
 
689258
 	* gdb.rust/simple.rs: Rename second variable "v".
689258
diff --git a/gdb/testsuite/README b/gdb/testsuite/README
689258
--- a/gdb/testsuite/README
689258
+++ b/gdb/testsuite/README
689258
@@ -259,6 +259,20 @@ This make (not runtest) variable is used to specify whether the
689258
 testsuite preloads the read1.so library into expect.  Any non-empty
689258
 value means true.  See "Race detection" below.
689258
 
689258
+GDB_TEST_SOCKETHOST
689258
+
689258
+This variable can provide the hostname/address that should be used
689258
+when performing GDBserver-related tests.  This is useful in some
689258
+situations, e.g., when you want to test the IPv6 connectivity of GDB
689258
+and GDBserver, or when using a different hostname/address is needed.
689258
+For example, to make GDB and GDBserver use IPv6-only connections, you
689258
+can do:
689258
+
689258
+	make check TESTS="gdb.server/*.exp" RUNTESTFLAGS='GDB_TEST_SOCKETHOST=tcp6:[::1]'
689258
+
689258
+Note that only a hostname/address can be provided, without a port
689258
+number.
689258
+
689258
 Race detection
689258
 **************
689258
 
689258
diff --git a/gdb/testsuite/boards/native-extended-gdbserver.exp b/gdb/testsuite/boards/native-extended-gdbserver.exp
689258
--- a/gdb/testsuite/boards/native-extended-gdbserver.exp
689258
+++ b/gdb/testsuite/boards/native-extended-gdbserver.exp
689258
@@ -24,8 +24,6 @@ load_generic_config "extended-gdbserver"
689258
 load_board_description "gdbserver-base"
689258
 load_board_description "local-board"
689258
 
689258
-set_board_info sockethost "localhost:"
689258
-
689258
 # We will be using the extended GDB remote protocol.
689258
 set_board_info gdb_protocol "extended-remote"
689258
 
689258
diff --git a/gdb/testsuite/boards/native-gdbserver.exp b/gdb/testsuite/boards/native-gdbserver.exp
689258
--- a/gdb/testsuite/boards/native-gdbserver.exp
689258
+++ b/gdb/testsuite/boards/native-gdbserver.exp
689258
@@ -30,7 +30,6 @@ set_board_info gdb,do_reload_on_run 1
689258
 # There's no support for argument-passing (yet).
689258
 set_board_info noargs 1
689258
 
689258
-set_board_info sockethost "localhost:"
689258
 set_board_info use_gdb_stub 1
689258
 set_board_info exit_is_reliable 1
689258
 
689258
diff --git a/gdb/testsuite/gdb.server/run-without-local-binary.exp b/gdb/testsuite/gdb.server/run-without-local-binary.exp
689258
--- a/gdb/testsuite/gdb.server/run-without-local-binary.exp
689258
+++ b/gdb/testsuite/gdb.server/run-without-local-binary.exp
689258
@@ -53,7 +53,7 @@ save_vars { GDBFLAGS } {
689258
     set use_gdb_stub 0
689258
 
689258
     gdb_test "target ${gdbserver_protocol} ${gdbserver_gdbport}" \
689258
-	"Remote debugging using $gdbserver_gdbport" \
689258
+	"Remote debugging using [string_to_regexp $gdbserver_gdbport]" \
689258
 	"connect to gdbserver"
689258
 
689258
     gdb_test "run" \
689258
diff --git a/gdb/testsuite/gdb.server/server-connect.exp b/gdb/testsuite/gdb.server/server-connect.exp
689258
new file mode 100644
689258
--- /dev/null
689258
+++ b/gdb/testsuite/gdb.server/server-connect.exp
689258
@@ -0,0 +1,111 @@
689258
+# This testcase is part of GDB, the GNU debugger.
689258
+#
689258
+# Copyright 2018 Free Software Foundation, Inc.
689258
+#
689258
+# This program is free software; you can redistribute it and/or modify
689258
+# it under the terms of the GNU General Public License as published by
689258
+# the Free Software Foundation; either version 3 of the License, or
689258
+# (at your option) any later version.
689258
+#
689258
+# This program is distributed in the hope that it will be useful,
689258
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
689258
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
689258
+# GNU General Public License for more details.
689258
+#
689258
+# You should have received a copy of the GNU General Public License
689258
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
689258
+
689258
+# Test multiple types of connection (IPv4, IPv6, TCP, UDP) and make
689258
+# sure both gdbserver and GDB work.
689258
+
689258
+load_lib gdbserver-support.exp
689258
+
689258
+standard_testfile normal.c
689258
+
689258
+if {[skip_gdbserver_tests]} {
689258
+    return 0
689258
+}
689258
+
689258
+# We want to have control over where we start gdbserver.
689258
+if { [is_remote target] } {
689258
+    return 0
689258
+}
689258
+
689258
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile debug] } {
689258
+    return -1
689258
+}
689258
+
689258
+# Make sure we're disconnected, in case we're testing with an
689258
+# extended-remote board, therefore already connected.
689258
+gdb_test "disconnect" ".*"
689258
+
689258
+set target_exec [gdbserver_download_current_prog]
689258
+
689258
+# An array containing the test instructions for each scenario.  The
689258
+# description of each field is as follows:
689258
+#
689258
+# - The connection specification to be used when starting
689258
+#   gdbserver/GDB.  This string will be used to set the
689258
+#   GDB_TEST_SOCKETHOST when calling gdbserver_start.
689258
+#
689258
+# - A flag indicating whether gdbserver should fail when we attempt to
689258
+#   start it.  Useful when testing erroneous connection specs such as
689258
+#   "tcp8:".
689258
+#
689258
+# - The prefix that should be prepended to the test messages.
689258
+set test_params \
689258
+    { \
689258
+	  { "tcp4:127.0.0.1" 0 "tcp4" } \
689258
+	  { "tcp6:::1"       0 "tcp6" } \
689258
+	  { "tcp6:[::1]"     0 "tcp6-with-brackets" } \
689258
+	  { "tcp:localhost"  0 "tcp" } \
689258
+	  { "udp4:127.0.0.1" 0 "udp4" } \
689258
+	  { "udp6:::1"       0 "udp6" } \
689258
+	  { "udp6:[::1]"     0 "udp6-with-brackets" } \
689258
+	  { "tcp8:123"       1 "tcp8" } \
689258
+	  { "udp123:::"      1 "udp123" } \
689258
+	  { "garbage:1234"   1 "garbage:1234" } \
689258
+    }
689258
+
689258
+# The best way to test different types of connections is to set the
689258
+# GDB_TEST_SOCKETHOST variable accordingly.
689258
+save_vars { GDB_TEST_SOCKETHOST } {
689258
+    foreach line $test_params {
689258
+	set sockhost [lindex $line 0]
689258
+	set gdbserver_should_fail [lindex $line 1]
689258
+	set prefix [lindex $line 2]
689258
+
689258
+	with_test_prefix $prefix {
689258
+	    set GDB_TEST_SOCKETHOST $sockhost
689258
+	    set test "start gdbserver"
689258
+
689258
+	    # Try to start gdbserver.
689258
+	    set catchres [catch {set res [gdbserver_start "" $target_exec]} errmsg]
689258
+
689258
+	    if { $catchres != 0 } {
689258
+		if { $gdbserver_should_fail } {
689258
+		    pass "$test: gdbserver failed as expected"
689258
+		} else {
689258
+		    fail "$test: $errmsg"
689258
+		}
689258
+		continue
689258
+	    } else {
689258
+		if { $gdbserver_should_fail } {
689258
+		    fail "$test: gdbserver should fail but did not"
689258
+		} else {
689258
+		    pass "$test"
689258
+		}
689258
+	    }
689258
+
689258
+	    set gdbserver_protocol [lindex $res 0]
689258
+	    set gdbserver_gdbport [lindex $res 1]
689258
+	    set test "connect to gdbserver using $sockhost"
689258
+
689258
+	    if { [gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] == 0 } {
689258
+		pass $test
689258
+	    } else {
689258
+		fail $test
689258
+	    }
689258
+	}
689258
+    }
689258
+}
689258
diff --git a/gdb/testsuite/lib/gdbserver-support.exp b/gdb/testsuite/lib/gdbserver-support.exp
689258
--- a/gdb/testsuite/lib/gdbserver-support.exp
689258
+++ b/gdb/testsuite/lib/gdbserver-support.exp
689258
@@ -211,7 +211,7 @@ proc gdbserver_default_get_remote_address { host port } {
689258
 # Default routine to compute the "comm" argument for gdbserver.
689258
 
689258
 proc gdbserver_default_get_comm_port { port } {
689258
-    return ":$port"
689258
+    return "$port"
689258
 }
689258
 
689258
 # Start a gdbserver process with initial OPTIONS and trailing ARGUMENTS.
689258
@@ -221,6 +221,7 @@ proc gdbserver_default_get_comm_port { port } {
689258
 
689258
 proc gdbserver_start { options arguments } {
689258
     global portnum
689258
+    global GDB_TEST_SOCKETHOST
689258
 
689258
     # Port id -- either specified in baseboard file, or managed here.
689258
     if [target_info exists gdb,socketport] {
689258
@@ -231,10 +232,22 @@ proc gdbserver_start { options arguments } {
689258
     }
689258
 
689258
     # Extract the local and remote host ids from the target board struct.
689258
-    if [target_info exists sockethost] {
689258
+    if { [info exists GDB_TEST_SOCKETHOST] } {
689258
+	# The user is not supposed to provide a port number, just a
689258
+	# hostname/address, therefore we add the trailing ":" here.
689258
+	set debughost "${GDB_TEST_SOCKETHOST}:"
689258
+	# Escape open and close square brackets.
689258
+	set debughost_tmp [string map { [ \\[ ] \\] } $debughost]
689258
+	# We need a "gdbserver" version of the debughost, which will
689258
+	# have the possible connection prefix stripped.  This is
689258
+	# because gdbserver currently doesn't recognize the prefixes.
689258
+	regsub -all "^\(tcp:|udp:|tcp4:|udp4:|tcp6:|udp6:\)" $debughost_tmp "" debughost_gdbserver
689258
+    } elseif [target_info exists sockethost] {
689258
 	set debughost [target_info sockethost]
689258
+	set debughost_gdbserver $debughost
689258
     } else {
689258
 	set debughost "localhost:"
689258
+	set debughost_gdbserver $debughost
689258
     }
689258
 
689258
     # Some boards use a different value for the port that is passed to
689258
@@ -277,8 +290,14 @@ proc gdbserver_start { options arguments } {
689258
 	if { $options != "" } {
689258
 	    append gdbserver_command " $options"
689258
 	}
689258
+	if { $debughost_gdbserver != "" } {
689258
+	    append gdbserver_command " $debughost_gdbserver"
689258
+	}
689258
 	if { $portnum != "" } {
689258
-	    append gdbserver_command " [$get_comm_port $portnum]"
689258
+	    if { $debughost_gdbserver == "" } {
689258
+		append gdbserver_command " "
689258
+	    }
689258
+	    append gdbserver_command "[$get_comm_port $portnum]"
689258
 	}
689258
 	if { $arguments != "" } {
689258
 	    append gdbserver_command " $arguments"
689258
@@ -307,6 +326,9 @@ proc gdbserver_start { options arguments } {
689258
 		    continue
689258
 		}
689258
 	    }
689258
+	    -re ".*: cannot resolve name: Name or service not known\r\n" {
689258
+		error "gdbserver cannot resolve name."
689258
+	    }
689258
 	    timeout {
689258
 		error "Timeout waiting for gdbserver response."
689258
 	    }
689258
diff --git a/gdb/unittests/parse-connection-spec-selftests.c b/gdb/unittests/parse-connection-spec-selftests.c
689258
new file mode 100644
689258
--- /dev/null
689258
+++ b/gdb/unittests/parse-connection-spec-selftests.c
689258
@@ -0,0 +1,249 @@
689258
+/* Self tests for parsing connection specs for GDB, the GNU debugger.
689258
+
689258
+   Copyright (C) 2018 Free Software Foundation, Inc.
689258
+
689258
+   This file is part of GDB.
689258
+
689258
+   This program is free software; you can redistribute it and/or modify
689258
+   it under the terms of the GNU General Public License as published by
689258
+   the Free Software Foundation; either version 3 of the License, or
689258
+   (at your option) any later version.
689258
+
689258
+   This program is distributed in the hope that it will be useful,
689258
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
689258
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
689258
+   GNU General Public License for more details.
689258
+
689258
+   You should have received a copy of the GNU General Public License
689258
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
689258
+
689258
+#include "defs.h"
689258
+#include "selftest.h"
689258
+#include "common/netstuff.h"
689258
+#include "diagnostics.h"
689258
+#ifdef USE_WIN32API
689258
+#include <winsock2.h>
689258
+#include <wspiapi.h>
689258
+#else
689258
+#include <netinet/in.h>
689258
+#include <arpa/inet.h>
689258
+#include <netdb.h>
689258
+#include <sys/socket.h>
689258
+#include <netinet/tcp.h>
689258
+#endif
689258
+
689258
+namespace selftests {
689258
+namespace parse_connection_spec_tests {
689258
+
689258
+/* Auxiliary struct that holds info about a specific test for a
689258
+   connection spec.  */
689258
+
689258
+struct parse_conn_test
689258
+{
689258
+  /* The connection spec.  */
689258
+  const char *connspec;
689258
+
689258
+  /* Expected result from 'parse_connection_spec'.  */
689258
+  parsed_connection_spec expected_result;
689258
+
689258
+  /* True if this test should fail, false otherwise.  If true, only
689258
+     the CONNSPEC field should be considered as valid.  */
689258
+  bool should_fail;
689258
+
689258
+  /* The expected AI_FAMILY to be found on the 'struct addrinfo'
689258
+     HINT.  */
689258
+  int exp_ai_family;
689258
+
689258
+  /* The expected AI_SOCKTYPE to be found on the 'struct addrinfo'
689258
+     HINT.  */
689258
+  int exp_ai_socktype;
689258
+
689258
+  /* The expected AI_PROTOCOL to be found on the 'struct addrinfo'
689258
+     HINT.  */
689258
+  int exp_ai_protocol;
689258
+};
689258
+
689258
+/* Some defines to help us fill a 'struct parse_conn_test'.  */
689258
+
689258
+/* Initialize a full entry.  */
689258
+#define INIT_ENTRY(ADDR, EXP_HOST, EXP_PORT, SHOULD_FAIL, EXP_AI_FAMILY, \
689258
+		   EXP_AI_SOCKTYPE, EXP_AI_PROTOCOL)			\
689258
+  { ADDR, { EXP_HOST, EXP_PORT }, SHOULD_FAIL, EXP_AI_FAMILY, \
689258
+    EXP_AI_SOCKTYPE, EXP_AI_PROTOCOL }
689258
+
689258
+/* Initialize an unprefixed entry.  In this case, we don't expect
689258
+   anything on the 'struct addrinfo' HINT.  */
689258
+#define INIT_UNPREFIXED_ENTRY(ADDR, EXP_HOST, EXP_PORT) \
689258
+  INIT_ENTRY (ADDR, EXP_HOST, EXP_PORT, false, 0, 0, 0)
689258
+
689258
+/* Initialized an unprefixed IPv6 entry.  In this case, we don't
689258
+   expect anything on the 'struct addrinfo' HINT.  */
689258
+#define INIT_UNPREFIXED_IPV6_ENTRY(ADDR, EXP_HOST, EXP_PORT) \
689258
+  INIT_ENTRY (ADDR, EXP_HOST, EXP_PORT, false, AF_INET6, 0, 0)
689258
+
689258
+/* Initialize a prefixed entry.  */
689258
+#define INIT_PREFIXED_ENTRY(ADDR, EXP_HOST, EXP_PORT, EXP_AI_FAMILY, \
689258
+			    EXP_AI_SOCKTYPE, EXP_AI_PROTOCOL) \
689258
+  INIT_ENTRY (ADDR, EXP_HOST, EXP_PORT, false, EXP_AI_FAMILY, \
689258
+	      EXP_AI_SOCKTYPE, EXP_AI_PROTOCOL)
689258
+
689258
+/* Initialize an entry prefixed with "tcp4:".  */
689258
+#define INIT_PREFIXED_IPV4_TCP(ADDR, EXP_HOST, EXP_PORT) \
689258
+  INIT_PREFIXED_ENTRY (ADDR, EXP_HOST, EXP_PORT, AF_INET, SOCK_STREAM, \
689258
+		       IPPROTO_TCP)
689258
+
689258
+/* Initialize an entry prefixed with "tcp6:".  */
689258
+#define INIT_PREFIXED_IPV6_TCP(ADDR, EXP_HOST, EXP_PORT) \
689258
+  INIT_PREFIXED_ENTRY (ADDR, EXP_HOST, EXP_PORT, AF_INET6, SOCK_STREAM, \
689258
+		       IPPROTO_TCP)
689258
+
689258
+/* Initialize an entry prefixed with "udp4:".  */
689258
+#define INIT_PREFIXED_IPV4_UDP(ADDR, EXP_HOST, EXP_PORT) \
689258
+  INIT_PREFIXED_ENTRY (ADDR, EXP_HOST, EXP_PORT, AF_INET, SOCK_DGRAM, \
689258
+		       IPPROTO_UDP)
689258
+
689258
+/* Initialize an entry prefixed with "udp6:".  */
689258
+#define INIT_PREFIXED_IPV6_UDP(ADDR, EXP_HOST, EXP_PORT) \
689258
+  INIT_PREFIXED_ENTRY (ADDR, EXP_HOST, EXP_PORT, AF_INET6, SOCK_DGRAM, \
689258
+		       IPPROTO_UDP)
689258
+
689258
+/* Initialize a bogus entry, i.e., a connection spec that should
689258
+   fail.  */
689258
+#define INIT_BOGUS_ENTRY(ADDR) \
689258
+  INIT_ENTRY (ADDR, "", "", true, 0, 0, 0)
689258
+
689258
+/* The variable which holds all of our tests.  */
689258
+
689258
+static const parse_conn_test conn_test[] =
689258
+  {
689258
+    /* Unprefixed addresses.  */
689258
+
689258
+    /* IPv4, host and port present.  */
689258
+    INIT_UNPREFIXED_ENTRY ("127.0.0.1:1234", "127.0.0.1", "1234"),
689258
+    /* IPv4, only host.  */
689258
+    INIT_UNPREFIXED_ENTRY ("127.0.0.1", "127.0.0.1", ""),
689258
+    /* IPv4, missing port.  */
689258
+    INIT_UNPREFIXED_ENTRY ("127.0.0.1:", "127.0.0.1", ""),
689258
+
689258
+    /* IPv6, host and port present, no brackets.  */
689258
+    INIT_UNPREFIXED_ENTRY ("::1:1234", "::1", "1234"),
689258
+    /* IPv6, missing port, no brackets.  */
689258
+    INIT_UNPREFIXED_ENTRY ("::1:", "::1", ""),
689258
+    /* IPv6, host and port present, with brackets.  */
689258
+    INIT_UNPREFIXED_IPV6_ENTRY ("[::1]:1234", "::1", "1234"),
689258
+    /* IPv6, only host, with brackets.  */
689258
+    INIT_UNPREFIXED_IPV6_ENTRY ("[::1]", "::1", ""),
689258
+    /* IPv6, missing port, with brackets.  */
689258
+    INIT_UNPREFIXED_IPV6_ENTRY ("[::1]:", "::1", ""),
689258
+
689258
+    /* Unspecified, only port.  */
689258
+    INIT_UNPREFIXED_ENTRY (":1234", "localhost", "1234"),
689258
+
689258
+    /* Prefixed addresses.  */
689258
+
689258
+    /* Prefixed "tcp4:" IPv4, host and port presents.  */
689258
+    INIT_PREFIXED_IPV4_TCP ("tcp4:127.0.0.1:1234", "127.0.0.1", "1234"),
689258
+    /* Prefixed "tcp4:" IPv4, only port.  */
689258
+    INIT_PREFIXED_IPV4_TCP ("tcp4::1234", "localhost", "1234"),
689258
+    /* Prefixed "tcp4:" IPv4, only host.  */
689258
+    INIT_PREFIXED_IPV4_TCP ("tcp4:127.0.0.1", "127.0.0.1", ""),
689258
+    /* Prefixed "tcp4:" IPv4, missing port.  */
689258
+    INIT_PREFIXED_IPV4_TCP ("tcp4:127.0.0.1:", "127.0.0.1", ""),
689258
+
689258
+    /* Prefixed "udp4:" IPv4, host and port present.  */
689258
+    INIT_PREFIXED_IPV4_UDP ("udp4:127.0.0.1:1234", "127.0.0.1", "1234"),
689258
+    /* Prefixed "udp4:" IPv4, only port.  */
689258
+    INIT_PREFIXED_IPV4_UDP ("udp4::1234", "localhost", "1234"),
689258
+    /* Prefixed "udp4:" IPv4, only host.  */
689258
+    INIT_PREFIXED_IPV4_UDP ("udp4:127.0.0.1", "127.0.0.1", ""),
689258
+    /* Prefixed "udp4:" IPv4, missing port.  */
689258
+    INIT_PREFIXED_IPV4_UDP ("udp4:127.0.0.1:", "127.0.0.1", ""),
689258
+
689258
+
689258
+    /* Prefixed "tcp6:" IPv6, host and port present.  */
689258
+    INIT_PREFIXED_IPV6_TCP ("tcp6:::1:1234", "::1", "1234"),
689258
+    /* Prefixed "tcp6:" IPv6, only port.  */
689258
+    INIT_PREFIXED_IPV6_TCP ("tcp6::1234", "localhost", "1234"),
689258
+    /* Prefixed "tcp6:" IPv6, only host.  */
689258
+    //INIT_PREFIXED_IPV6_TCP ("tcp6:::1", "::1", ""),
689258
+    /* Prefixed "tcp6:" IPv6, missing port.  */
689258
+    INIT_PREFIXED_IPV6_TCP ("tcp6:::1:", "::1", ""),
689258
+
689258
+    /* Prefixed "udp6:" IPv6, host and port present.  */
689258
+    INIT_PREFIXED_IPV6_UDP ("udp6:::1:1234", "::1", "1234"),
689258
+    /* Prefixed "udp6:" IPv6, only port.  */
689258
+    INIT_PREFIXED_IPV6_UDP ("udp6::1234", "localhost", "1234"),
689258
+    /* Prefixed "udp6:" IPv6, only host.  */
689258
+    //INIT_PREFIXED_IPV6_UDP ("udp6:::1", "::1", ""),
689258
+    /* Prefixed "udp6:" IPv6, missing port.  */
689258
+    INIT_PREFIXED_IPV6_UDP ("udp6:::1:", "::1", ""),
689258
+
689258
+    /* Prefixed "tcp6:" IPv6 with brackets, host and port present.  */
689258
+    INIT_PREFIXED_IPV6_TCP ("tcp6:[::1]:1234", "::1", "1234"),
689258
+    /* Prefixed "tcp6:" IPv6 with brackets, only host.  */
689258
+    INIT_PREFIXED_IPV6_TCP ("tcp6:[::1]", "::1", ""),
689258
+    /* Prefixed "tcp6:" IPv6 with brackets, missing port.  */
689258
+    INIT_PREFIXED_IPV6_TCP ("tcp6:[::1]:", "::1", ""),
689258
+
689258
+    /* Prefixed "udp6:" IPv6 with brackets, host and port present.  */
689258
+    INIT_PREFIXED_IPV6_UDP ("udp6:[::1]:1234", "::1", "1234"),
689258
+    /* Prefixed "udp6:" IPv6 with brackets, only host.  */
689258
+    INIT_PREFIXED_IPV6_UDP ("udp6:[::1]", "::1", ""),
689258
+    /* Prefixed "udp6:" IPv6 with brackets, missing port.  */
689258
+    INIT_PREFIXED_IPV6_UDP ("udp6:[::1]:", "::1", ""),
689258
+
689258
+
689258
+    /* Bogus addresses.  */
689258
+    INIT_BOGUS_ENTRY ("tcp6:[::1]123:44"),
689258
+    INIT_BOGUS_ENTRY ("[::1"),
689258
+    INIT_BOGUS_ENTRY ("tcp6:::1]:"),
689258
+  };
689258
+
689258
+/* Test a connection spec C.  */
689258
+
689258
+static void
689258
+test_conn (const parse_conn_test &c)
689258
+{
689258
+  struct addrinfo hint;
689258
+  parsed_connection_spec ret;
689258
+
689258
+  memset (&hint, 0, sizeof (hint));
689258
+
689258
+  TRY
689258
+    {
689258
+      ret = parse_connection_spec (c.connspec, &hint);
689258
+    }
689258
+  CATCH (ex, RETURN_MASK_ERROR)
689258
+    {
689258
+      /* If we caught an error, we should check if this connection
689258
+	 spec was supposed to fail.  */
689258
+      SELF_CHECK (c.should_fail);
689258
+      return;
689258
+    }
689258
+  END_CATCH
689258
+
689258
+  SELF_CHECK (!c.should_fail);
689258
+  SELF_CHECK (ret.host_str == c.expected_result.host_str);
689258
+  SELF_CHECK (ret.port_str == c.expected_result.port_str);
689258
+  SELF_CHECK (hint.ai_family == c.exp_ai_family);
689258
+  SELF_CHECK (hint.ai_socktype == c.exp_ai_socktype);
689258
+  SELF_CHECK (hint.ai_protocol == c.exp_ai_protocol);
689258
+}
689258
+
689258
+/* Run the tests associated with parsing connection specs.  */
689258
+
689258
+static void
689258
+run_tests ()
689258
+{
689258
+  for (const parse_conn_test &c : conn_test)
689258
+    test_conn (c);
689258
+}
689258
+} /* namespace parse_connection_spec_tests */
689258
+} /* namespace selftests */
689258
+
689258
+void
689258
+_initialize_parse_connection_spec_selftests ()
689258
+{
689258
+  selftests::register_test ("parse_connection_spec",
689258
+			    selftests::parse_connection_spec_tests::run_tests);
689258
+}