From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 74140 invoked by alias); 10 Feb 2016 11:43:45 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 74124 invoked by uid 89); 10 Feb 2016 11:43:44 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=4007, aspx, UD:3.html, man3 X-HELO: mail-ig0-f171.google.com Received: from mail-ig0-f171.google.com (HELO mail-ig0-f171.google.com) (209.85.213.171) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 10 Feb 2016 11:43:42 +0000 Received: by mail-ig0-f171.google.com with SMTP id 5so12372664igt.0 for ; Wed, 10 Feb 2016 03:43:42 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=FDfchnspyq2A68DoYBdYEu4iBOBlOQ6y+ZLKFR/OQmY=; b=g7cEE7BQI71+bQAFkyBmlWXwfEb2uEb2xdfbI5DKWuOl7uznDlp1xdddBRGoTFLRAA SfcH1XStkyWoXIhfBpboJvMxE9AWVM9ZEg8CORRVchG+fMtWarhIZktk210Ukln8kiRp qjMmLZRmvryHG8LnDpNkYKV21DyonP2sBwDAcGhALZZdA5oZot6ARXwOONg2pON2LL3O 8mqRge1vhhv9YAtdibIkqxYimMuLncW+3j7XrOn1nynNz/VDw02H5mWDT/Z2dxJjekFY HR/A1Xg0XcP+HdgUycTTp8+lClaaTKNEmfo238SHoSRgLOD0fau6j3EjxBJ5niuZjs4u CQzQ== X-Gm-Message-State: AG10YOQzcGSW/0fXnMCAyyLROZR9hwRpZ/0782P8y4TwM4HuNKjGNg4W+JD9ZvYBonHg9fT+VVvNgdMgu8LGPA== MIME-Version: 1.0 X-Received: by 10.50.112.102 with SMTP id ip6mr9663539igb.88.1455104620712; Wed, 10 Feb 2016 03:43:40 -0800 (PST) Received: by 10.36.197.195 with HTTP; Wed, 10 Feb 2016 03:43:40 -0800 (PST) In-Reply-To: <831t8ldc80.fsf@gnu.org> References: <831t8ldc80.fsf@gnu.org> Date: Wed, 10 Feb 2016 11:43:00 -0000 Message-ID: Subject: Re: [PATCH] supports IPv6 only remote target From: Tsutomu Seki To: Eli Zaretskii Cc: gdb-patches@sourceware.org Content-Type: text/plain; charset=UTF-8 X-SW-Source: 2016-02/txt/msg00275.txt.bz2 Hi Eli, Thank you to review. > Please use @code with the address string fe80::1. Changed address to be "@code{fe80::1%eth1}", to include scope id as written later. > This example seems to imply that more than just taking brackets > is required. Your are right. This implies address/port separation rule and address/scope separation rule. The former should be documented, because address/port separation is done by the application before passing them to getaddrinfo. > Should we tell more about that? On the other hand, the latter is difficult to document (for me) in generic manner, because %-style scope-id notation depends on implementation of getaddrinfo. As far as I googled; - Ubuntu: noted; http://manpages.ubuntu.com/manpages/precise/en/man3/getaddrinfo.3.html > getaddrinfo() supports the address%scope-id notation for specifying the > IPv6 scope-ID. - FreeBSD: documented; https://www.freebsd.org/cgi/man.cgi?query=getaddrinfo&sektion=3 > This implementation of getaddrinfo() allows numeric IPv6 address > notation with scope identifier, as documented in chapter 11 of > RFC 4007. - Windows: it seems to be supported, but not documented; https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/aa385325(v=vs.85).aspx To avoid this ambiguity whether OS supports this manner of separation, I want to suggest to use whole "fe80::1%eth1" including scope id as an example of "numeric IPv6 address". > The service name defaults to @code{"gdbremote"} I think quotation is not needed if @code is used. Please review another example I added to show how to use service name explicitly. > I guess you mean "on the port assigned to that service", yes? Yes. > I think this will break the build with mingw.org's MinGW. It doesn't > have wspiapi.h, AFAIK. What exactly is needed from that header? It is needed to support getaddrinfo() on Windows 2000 and older versions. What can I do for it? The easiest solution is to replace with , but Windows 2000 support (as a host) would be dropped. Regards, Seki, Tsutomu --- gdb/ChangeLog: * ser-tcp.c (net_open): Use getaddrinfo instead of gethostbyname (net_open): Add IPv6 numerical address support (net_open): Use "gdbremote" as default service name gdb/doc/ChangeLog: * gdb.texinfo (Remote Connection Commands): Update to mention IPv6 numerical address and default service name. --- gdb/doc/gdb.texinfo | 37 +++++++++++++++++++--- gdb/ser-tcp.c | 91 ++++++++++++++++++++++++++++++++++------------------- 2 files changed, 92 insertions(+), 36 deletions(-) --- diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 2d09d13..ebc0263 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -19571,10 +19571,11 @@ If you're using a serial line, you may want to give @value{GDBN} the @cindex @acronym{TCP} port, @code{target remote} Debug using a @acronym{TCP} connection to @var{port} on @var{host}. The @var{host} may be either a host name or a numeric @acronym{IP} -address; @var{port} must be a decimal number. The @var{host} could be -the target machine itself, if it is directly connected to the net, or -it might be a terminal server which in turn has a serial line to the -target. +address or a numeric @acronym{IPv6} address enclosed in square +brackets; @var{port} may be either a service name or a decimal number. +The @var{host} could be the target machine itself, if it is directly +connected to the net, or it might be a terminal server which in turn +has a serial line to the target. For example, to connect to port 2828 on a terminal server named @code{manyfarms}: @@ -19583,6 +19584,14 @@ For example, to connect to port 2828 on a terminal server named target remote manyfarms:2828 @end smallexample +Numeric @acronym{IPv6} address must be enclosed in square brackets. +For example, to connect to port 2159 of a target which has +@acronym{IPv6} address @code{fe80::1%eth1}: + +@smallexample +target remote [fe80::1%eth1]:2159 +@end smallexample + If your remote target is actually running on the same machine as your debugger session (e.g.@: a simulator for your target running on the same host), you can omit the hostname. For example, to connect to @@ -19591,6 +19600,26 @@ port 1234 on your local machine: @smallexample target remote :1234 @end smallexample + +If the service name is present in service list (e.g.@: @file{/etc/services} +on @sc{gnu}/Linux systems) on your local machine, and target is +listening on the port assigned to that service, you can use +human-friendly name instead of the port number. For example, +to connect to service named @code{icepick} on a target machine +named @code{stormstown}: + +@smallexample +target remote stormstown:icepick +@end smallexample + +The service name defaults to @code{gdbremote}. If your target is +listening on the port assigned to @code{gdbremote}, you can omit the +service name. For example, to connect to service @code{gdbremote} +on your local machine: + +@smallexample +target remote : +@end smallexample @noindent Note that the colon is still required here. diff --git a/gdb/ser-tcp.c b/gdb/ser-tcp.c index df3af4c..0123480 100644 --- a/gdb/ser-tcp.c +++ b/gdb/ser-tcp.c @@ -39,6 +39,7 @@ #ifdef USE_WIN32API #include +#include #ifndef ETIMEDOUT #define ETIMEDOUT WSAETIMEDOUT #endif @@ -156,11 +157,10 @@ int net_open (struct serial *scb, const char *name) { char hostname[100]; - const char *port_str; - int n, port, tmp; + const char *port_str, *host_str; + int n, tmp, err; int use_udp; - struct hostent *hostent; - struct sockaddr_in sockaddr; + struct addrinfo *ai, hint; #ifdef USE_WIN32API u_long ioarg; #else @@ -177,43 +177,65 @@ net_open (struct serial *scb, const char *name) else if (startswith (name, "tcp:")) name = name + 4; - port_str = strchr (name, ':'); + if (name[0] == '[') + { + const char *end = strchr(name + 1, ']'); + if (!end) + error (_("net_open: No close bracket in host name!")); + + tmp = min (end - name - 1, (int) sizeof hostname - 1); + strncpy (hostname, name + 1, tmp); /* Don't want brackets. */ + hostname[tmp] = '\0'; /* Tie off host name. */ + host_str = hostname; + port_str = end + 1; + } + else if ((port_str = strrchr(name, ':')) != NULL) + { + tmp = min (port_str - name, (int) sizeof hostname - 1); + strncpy (hostname, name, tmp); /* Don't want colon. */ + hostname[tmp] = '\0'; /* Tie off host name. */ + host_str = hostname; + } + else + { + host_str = name; + port_str = NULL; + } - if (!port_str) - error (_("net_open: No colon in host name!")); /* Shouldn't ever - happen. */ + if (port_str != NULL && port_str[0] == ':') + port_str++; - tmp = min (port_str - name, (int) sizeof hostname - 1); - strncpy (hostname, name, tmp); /* Don't want colon. */ - hostname[tmp] = '\000'; /* Tie off host name. */ - port = atoi (port_str + 1); + /* Default service name is gdbremote. */ + if (port_str == NULL || port_str[0] == '\0') + port_str = "gdbremote"; /* Default hostname is localhost. */ - if (!hostname[0]) - strcpy (hostname, "localhost"); - - hostent = gethostbyname (hostname); - if (!hostent) + if (host_str[0] == '\0') + host_str = "localhost"; + + memset(&hint, 0, sizeof hint); + hint.ai_family = AF_UNSPEC; + hint.ai_socktype = use_udp ? SOCK_DGRAM : SOCK_STREAM; + hint.ai_flags = 0; + hint.ai_protocol = use_udp ? IPPROTO_UDP : IPPROTO_TCP; + hint.ai_canonname = NULL; + hint.ai_addr = NULL; + hint.ai_next = NULL; + ai = NULL; + + if ((err = getaddrinfo (host_str, port_str, &hint, &ai)) != 0) { - fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname); + fprintf_unfiltered (gdb_stderr, "%s: %s\n", name, gai_strerror(err)); errno = ENOENT; return -1; } - sockaddr.sin_family = PF_INET; - sockaddr.sin_port = htons (port); - memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr, - sizeof (struct in_addr)); - retry: - if (use_udp) - scb->fd = gdb_socket_cloexec (PF_INET, SOCK_DGRAM, 0); - else - scb->fd = gdb_socket_cloexec (PF_INET, SOCK_STREAM, 0); + scb->fd = gdb_socket_cloexec (ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (scb->fd == -1) - return -1; + goto bailout; /* Set socket nonblocking. */ ioarg = 1; @@ -221,7 +243,7 @@ net_open (struct serial *scb, const char *name) /* Use Non-blocking connect. connect() will return 0 if connected already. */ - n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr)); + n = connect (scb->fd, ai->ai_addr, ai->ai_addrlen); if (n < 0) { @@ -257,7 +279,7 @@ net_open (struct serial *scb, const char *name) { errno = err; net_close (scb); - return -1; + goto bailout; } /* Looks like we need to wait for the connect. */ @@ -269,7 +291,7 @@ net_open (struct serial *scb, const char *name) if (n < 0) { net_close (scb); - return -1; + goto bailout; } } @@ -301,7 +323,7 @@ net_open (struct serial *scb, const char *name) if (err) errno = err; net_close (scb); - return -1; + goto bailout; } } @@ -323,7 +345,12 @@ net_open (struct serial *scb, const char *name) signal (SIGPIPE, SIG_IGN); #endif + freeaddrinfo (ai); return 0; + + bailout: + freeaddrinfo (ai); + return -1; } void