From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26473 invoked by alias); 9 Feb 2016 13:50:02 -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 26437 invoked by uid 89); 9 Feb 2016 13:50:01 -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=debugger, fe80, 2159, listening X-HELO: mail-io0-f169.google.com Received: from mail-io0-f169.google.com (HELO mail-io0-f169.google.com) (209.85.223.169) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 09 Feb 2016 13:49:59 +0000 Received: by mail-io0-f169.google.com with SMTP id l127so9706340iof.3 for ; Tue, 09 Feb 2016 05:49:59 -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:date:message-id:subject:from:to :content-type; bh=Gg96hBCeU28DFvry5OcVRyB9MzF9nBk8INg4nkwAumU=; b=W76r3TVMX8hUOxnO09xMHjPhqgkojdHXO6iGitbtFRjihHD6KV2fHw+KzJSTf3k0zw V2Vk7puYcV3ScPp9w5Etbne5xVbox+e9GvrsSccMSdk7v4m/S1V80gLyd70WGvyGvebI xEsnYKQTDiA5g/JoPCh6gh1bnk4BIulmeJn3lbeKCmrZRWKmJjzDO/vfgOH3P+O4L7KL QJTLldgyD/0hD9iqxDi8TnAshE14XuYcsGk3TJkLPZghLDW5ri1SXjSfU/fMICuywmfQ 5RgHElRfHNKftNT5cehVkeGUx+Ldl7D19sGwGyOCbjVBoS98+qLMiLtKGd9kNhyk8kaW ZTlw== X-Gm-Message-State: AG10YOQNWEHBoYmoWWzIbQEvwY2uAh8yZDK36LfQYslb05dGvyfNE6YBQ5SynrJKprX92VAMvcvhy0tkh4cPWQ== MIME-Version: 1.0 X-Received: by 10.107.135.202 with SMTP id r71mr40329085ioi.129.1455025797833; Tue, 09 Feb 2016 05:49:57 -0800 (PST) Received: by 10.36.197.195 with HTTP; Tue, 9 Feb 2016 05:49:57 -0800 (PST) Date: Tue, 09 Feb 2016 13:50:00 -0000 Message-ID: Subject: [PATCH] supports IPv6 only remote target From: Tsutomu Seki To: gdb-patches@sourceware.org Content-Type: text/plain; charset=UTF-8 X-SW-Source: 2016-02/txt/msg00226.txt.bz2 Hi, While I'm trying to connect remote target that has only IPv6 (Link-Local) address, > $ getent hosts hogehoge.local > fe80::XXXX:XXff:feXX:XXXX hogehoge.local > $ arm-none-eabi-gdb > (gdb) target remote hogehoge.local:2159 I found gdb is sending packets for invalid address, > $ tcpdump -n "tcp port 2159" > 14:06:39.611372 IP 10.XX.XX.10.51012 > 254.128.0.0.2159: Flags [S], seq 4014569856, win 29200, options [mss 1460,sackOK,TS val 429376439 ecr 0,nop,wscale 7], length 0 > 14:06:40.608993 IP 10.XX.XX.10.51012 > 254.128.0.0.2159: Flags [S], seq 4014569856, win 29200, options [mss 1460,sackOK,TS val 429376689 ecr 0,nop,wscale 7], length 0 > ... and then, it fails to connect after few seconds. In addition to that, it seems port number is invalidly parsed when only colon, without decimal number was passed. I mean; > (gdb) target remote tcp:: will result to try to connect tcp port 0 on localhost. Forthcoming patch fixes these problem and add IPv6 support. Tested to build for --target=arm-none-eabi, with --host=x86_64-linux-gnu and i686-w64-mingw32, by applying the patch to a version 5-2015-q4-major of https://launchpad.net/gcc-arm-embedded, and to run on Ubuntu 14.04.3 and Windows 7 Enterprise SP1, respectively. Thanks in advance and sorry for my poor English. 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 | 27 +++++++++++++--- gdb/ser-tcp.c | 91 ++++++++++++++++++++++++++++++++++------------------- 2 files changed, 82 insertions(+), 36 deletions(-) diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 2d09d13..d696ce4 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -19565,16 +19565,17 @@ If you're using a serial line, you may want to give @value{GDBN} the @code{target} command. @item target remote @code{@var{host}:@var{port}} +@itemx target remote @code{[@var{host}]:@var{port}} @itemx target remote @code{tcp:@var{host}:@var{port}} @itemx target extended-remote @code{@var{host}:@var{port}} @itemx target extended-remote @code{tcp:@var{host}:@var{port}} @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; @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 +Numerical @acronym{IPv6} address must be enclosed in square brackets. +For example, to connect to port 2159 of a target which has IPv6 +link-local address fe80::1 on 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,16 @@ port 1234 on your local machine: @smallexample target remote :1234 @end smallexample + +The service name is default to ``gdbremote''. If the service name is +present in service list (e.g.@: @file{/etc/services} on @sc{gnu}/Linux +systems), and target is listening on assigned port, you can omit the +service name. For example, to connect to service ``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..4ed5f2a 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