[gdb/testsuite] Fix "unable to find usable gdb" error with cc-with-tweaks.exp
[deliverable/binutils-gdb.git] / gdb / common / netstuff.c
CommitLineData
c7ab0aef 1/* Operations on network stuff.
42a4f53d 2 Copyright (C) 2018-2019 Free Software Foundation, Inc.
c7ab0aef
SDJ
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19#include "common-defs.h"
20#include "netstuff.h"
21#include <algorithm>
22
23#ifdef USE_WIN32API
41fa577f
EZ
24#if _WIN32_WINNT < 0x0501
25# undef _WIN32_WINNT
26# define _WIN32_WINNT 0x0501
27#endif
28#include <ws2tcpip.h>
c7ab0aef
SDJ
29#else
30#include <netinet/in.h>
31#include <arpa/inet.h>
32#include <netdb.h>
33#include <sys/socket.h>
34#include <netinet/tcp.h>
35#endif
36
37/* See common/netstuff.h. */
38
39scoped_free_addrinfo::~scoped_free_addrinfo ()
40{
41 freeaddrinfo (m_res);
42}
43
44/* See common/netstuff.h. */
45
46parsed_connection_spec
47parse_connection_spec_without_prefix (std::string spec, struct addrinfo *hint)
48{
49 parsed_connection_spec ret;
50 size_t last_colon_pos = 0;
51 /* We're dealing with IPv6 if:
52
53 - ai_family is AF_INET6, or
54 - ai_family is not AF_INET, and
55 - spec[0] is '[', or
56 - the number of ':' on spec is greater than 1. */
57 bool is_ipv6 = (hint->ai_family == AF_INET6
58 || (hint->ai_family != AF_INET
59 && (spec[0] == '['
60 || std::count (spec.begin (),
61 spec.end (), ':') > 1)));
62
63 if (is_ipv6)
64 {
65 if (spec[0] == '[')
66 {
67 /* IPv6 addresses can be written as '[ADDR]:PORT', and we
68 support this notation. */
69 size_t close_bracket_pos = spec.find_first_of (']');
70
71 if (close_bracket_pos == std::string::npos)
72 error (_("Missing close bracket in hostname '%s'"),
73 spec.c_str ());
74
75 hint->ai_family = AF_INET6;
76
77 const char c = spec[close_bracket_pos + 1];
78
79 if (c == '\0')
80 last_colon_pos = std::string::npos;
81 else if (c != ':')
82 error (_("Invalid cruft after close bracket in '%s'"),
83 spec.c_str ());
84
85 /* Erase both '[' and ']'. */
86 spec.erase (0, 1);
87 spec.erase (close_bracket_pos - 1, 1);
88 }
89 else if (spec.find_first_of (']') != std::string::npos)
90 error (_("Missing open bracket in hostname '%s'"),
91 spec.c_str ());
92 }
93
94 if (last_colon_pos == 0)
95 last_colon_pos = spec.find_last_of (':');
96
97 /* The length of the hostname part. */
98 size_t host_len;
99
100 if (last_colon_pos != std::string::npos)
101 {
102 /* The user has provided a port. */
103 host_len = last_colon_pos;
104 ret.port_str = spec.substr (last_colon_pos + 1);
105 }
106 else
107 host_len = spec.size ();
108
109 ret.host_str = spec.substr (0, host_len);
110
111 /* Default hostname is localhost. */
112 if (ret.host_str.empty ())
113 ret.host_str = "localhost";
114
115 return ret;
116}
117
118/* See common/netstuff.h. */
119
120parsed_connection_spec
121parse_connection_spec (const char *spec, struct addrinfo *hint)
122{
123 /* Struct to hold the association between valid prefixes, their
124 family and socktype. */
125 struct host_prefix
126 {
127 /* The prefix. */
128 const char *prefix;
129
130 /* The 'ai_family'. */
131 int family;
132
133 /* The 'ai_socktype'. */
134 int socktype;
135 };
136 static const struct host_prefix prefixes[] =
137 {
138 { "udp:", AF_UNSPEC, SOCK_DGRAM },
139 { "tcp:", AF_UNSPEC, SOCK_STREAM },
140 { "udp4:", AF_INET, SOCK_DGRAM },
141 { "tcp4:", AF_INET, SOCK_STREAM },
142 { "udp6:", AF_INET6, SOCK_DGRAM },
143 { "tcp6:", AF_INET6, SOCK_STREAM },
144 };
145
146 for (const host_prefix prefix : prefixes)
147 if (startswith (spec, prefix.prefix))
148 {
149 spec += strlen (prefix.prefix);
150 hint->ai_family = prefix.family;
151 hint->ai_socktype = prefix.socktype;
152 hint->ai_protocol
153 = hint->ai_socktype == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP;
154 break;
155 }
156
157 return parse_connection_spec_without_prefix (spec, hint);
158}
This page took 0.082762 seconds and 4 git commands to generate.