parse-connection-spec-selftests.c revision 1.1.1.2 1 1.1 christos /* Self tests for parsing connection specs for GDB, the GNU debugger.
2 1.1 christos
3 1.1.1.2 christos Copyright (C) 2018-2020 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of GDB.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos #include "defs.h"
21 1.1.1.2 christos #include "gdbsupport/selftest.h"
22 1.1.1.2 christos #include "gdbsupport/netstuff.h"
23 1.1 christos #include "diagnostics.h"
24 1.1 christos #ifdef USE_WIN32API
25 1.1 christos #include <ws2tcpip.h>
26 1.1 christos #else
27 1.1 christos #include <netinet/in.h>
28 1.1 christos #include <arpa/inet.h>
29 1.1 christos #include <netdb.h>
30 1.1 christos #include <sys/socket.h>
31 1.1 christos #include <netinet/tcp.h>
32 1.1 christos #endif
33 1.1 christos
34 1.1 christos namespace selftests {
35 1.1 christos namespace parse_connection_spec_tests {
36 1.1 christos
37 1.1 christos /* Auxiliary struct that holds info about a specific test for a
38 1.1 christos connection spec. */
39 1.1 christos
40 1.1 christos struct parse_conn_test
41 1.1 christos {
42 1.1 christos /* The connection spec. */
43 1.1 christos const char *connspec;
44 1.1 christos
45 1.1 christos /* Expected result from 'parse_connection_spec'. */
46 1.1 christos parsed_connection_spec expected_result;
47 1.1 christos
48 1.1 christos /* True if this test should fail, false otherwise. If true, only
49 1.1 christos the CONNSPEC field should be considered as valid. */
50 1.1 christos bool should_fail;
51 1.1 christos
52 1.1 christos /* The expected AI_FAMILY to be found on the 'struct addrinfo'
53 1.1 christos HINT. */
54 1.1 christos int exp_ai_family;
55 1.1 christos
56 1.1 christos /* The expected AI_SOCKTYPE to be found on the 'struct addrinfo'
57 1.1 christos HINT. */
58 1.1 christos int exp_ai_socktype;
59 1.1 christos
60 1.1 christos /* The expected AI_PROTOCOL to be found on the 'struct addrinfo'
61 1.1 christos HINT. */
62 1.1 christos int exp_ai_protocol;
63 1.1 christos };
64 1.1 christos
65 1.1 christos /* Some defines to help us fill a 'struct parse_conn_test'. */
66 1.1 christos
67 1.1 christos /* Initialize a full entry. */
68 1.1 christos #define INIT_ENTRY(ADDR, EXP_HOST, EXP_PORT, SHOULD_FAIL, EXP_AI_FAMILY, \
69 1.1 christos EXP_AI_SOCKTYPE, EXP_AI_PROTOCOL) \
70 1.1 christos { ADDR, { EXP_HOST, EXP_PORT }, SHOULD_FAIL, EXP_AI_FAMILY, \
71 1.1 christos EXP_AI_SOCKTYPE, EXP_AI_PROTOCOL }
72 1.1 christos
73 1.1 christos /* Initialize an unprefixed entry. In this case, we don't expect
74 1.1 christos anything on the 'struct addrinfo' HINT. */
75 1.1 christos #define INIT_UNPREFIXED_ENTRY(ADDR, EXP_HOST, EXP_PORT) \
76 1.1 christos INIT_ENTRY (ADDR, EXP_HOST, EXP_PORT, false, 0, 0, 0)
77 1.1 christos
78 1.1 christos /* Initialized an unprefixed IPv6 entry. In this case, we don't
79 1.1 christos expect anything on the 'struct addrinfo' HINT. */
80 1.1 christos #define INIT_UNPREFIXED_IPV6_ENTRY(ADDR, EXP_HOST, EXP_PORT) \
81 1.1 christos INIT_ENTRY (ADDR, EXP_HOST, EXP_PORT, false, AF_INET6, 0, 0)
82 1.1 christos
83 1.1 christos /* Initialize a prefixed entry. */
84 1.1 christos #define INIT_PREFIXED_ENTRY(ADDR, EXP_HOST, EXP_PORT, EXP_AI_FAMILY, \
85 1.1 christos EXP_AI_SOCKTYPE, EXP_AI_PROTOCOL) \
86 1.1 christos INIT_ENTRY (ADDR, EXP_HOST, EXP_PORT, false, EXP_AI_FAMILY, \
87 1.1 christos EXP_AI_SOCKTYPE, EXP_AI_PROTOCOL)
88 1.1 christos
89 1.1 christos /* Initialize an entry prefixed with "tcp4:". */
90 1.1 christos #define INIT_PREFIXED_IPV4_TCP(ADDR, EXP_HOST, EXP_PORT) \
91 1.1 christos INIT_PREFIXED_ENTRY (ADDR, EXP_HOST, EXP_PORT, AF_INET, SOCK_STREAM, \
92 1.1 christos IPPROTO_TCP)
93 1.1 christos
94 1.1 christos /* Initialize an entry prefixed with "tcp6:". */
95 1.1 christos #define INIT_PREFIXED_IPV6_TCP(ADDR, EXP_HOST, EXP_PORT) \
96 1.1 christos INIT_PREFIXED_ENTRY (ADDR, EXP_HOST, EXP_PORT, AF_INET6, SOCK_STREAM, \
97 1.1 christos IPPROTO_TCP)
98 1.1 christos
99 1.1 christos /* Initialize an entry prefixed with "udp4:". */
100 1.1 christos #define INIT_PREFIXED_IPV4_UDP(ADDR, EXP_HOST, EXP_PORT) \
101 1.1 christos INIT_PREFIXED_ENTRY (ADDR, EXP_HOST, EXP_PORT, AF_INET, SOCK_DGRAM, \
102 1.1 christos IPPROTO_UDP)
103 1.1 christos
104 1.1 christos /* Initialize an entry prefixed with "udp6:". */
105 1.1 christos #define INIT_PREFIXED_IPV6_UDP(ADDR, EXP_HOST, EXP_PORT) \
106 1.1 christos INIT_PREFIXED_ENTRY (ADDR, EXP_HOST, EXP_PORT, AF_INET6, SOCK_DGRAM, \
107 1.1 christos IPPROTO_UDP)
108 1.1 christos
109 1.1 christos /* Initialize a bogus entry, i.e., a connection spec that should
110 1.1 christos fail. */
111 1.1 christos #define INIT_BOGUS_ENTRY(ADDR) \
112 1.1 christos INIT_ENTRY (ADDR, "", "", true, 0, 0, 0)
113 1.1 christos
114 1.1 christos /* The variable which holds all of our tests. */
115 1.1 christos
116 1.1 christos static const parse_conn_test conn_test[] =
117 1.1 christos {
118 1.1 christos /* Unprefixed addresses. */
119 1.1 christos
120 1.1 christos /* IPv4, host and port present. */
121 1.1 christos INIT_UNPREFIXED_ENTRY ("127.0.0.1:1234", "127.0.0.1", "1234"),
122 1.1 christos /* IPv4, only host. */
123 1.1 christos INIT_UNPREFIXED_ENTRY ("127.0.0.1", "127.0.0.1", ""),
124 1.1 christos /* IPv4, missing port. */
125 1.1 christos INIT_UNPREFIXED_ENTRY ("127.0.0.1:", "127.0.0.1", ""),
126 1.1 christos
127 1.1 christos /* IPv6, host and port present, no brackets. */
128 1.1 christos INIT_UNPREFIXED_ENTRY ("::1:1234", "::1", "1234"),
129 1.1 christos /* IPv6, missing port, no brackets. */
130 1.1 christos INIT_UNPREFIXED_ENTRY ("::1:", "::1", ""),
131 1.1 christos /* IPv6, host and port present, with brackets. */
132 1.1 christos INIT_UNPREFIXED_IPV6_ENTRY ("[::1]:1234", "::1", "1234"),
133 1.1 christos /* IPv6, only host, with brackets. */
134 1.1 christos INIT_UNPREFIXED_IPV6_ENTRY ("[::1]", "::1", ""),
135 1.1 christos /* IPv6, missing port, with brackets. */
136 1.1 christos INIT_UNPREFIXED_IPV6_ENTRY ("[::1]:", "::1", ""),
137 1.1 christos
138 1.1 christos /* Unspecified, only port. */
139 1.1 christos INIT_UNPREFIXED_ENTRY (":1234", "localhost", "1234"),
140 1.1 christos
141 1.1 christos /* Prefixed addresses. */
142 1.1 christos
143 1.1 christos /* Prefixed "tcp4:" IPv4, host and port presents. */
144 1.1 christos INIT_PREFIXED_IPV4_TCP ("tcp4:127.0.0.1:1234", "127.0.0.1", "1234"),
145 1.1 christos /* Prefixed "tcp4:" IPv4, only port. */
146 1.1 christos INIT_PREFIXED_IPV4_TCP ("tcp4::1234", "localhost", "1234"),
147 1.1 christos /* Prefixed "tcp4:" IPv4, only host. */
148 1.1 christos INIT_PREFIXED_IPV4_TCP ("tcp4:127.0.0.1", "127.0.0.1", ""),
149 1.1 christos /* Prefixed "tcp4:" IPv4, missing port. */
150 1.1 christos INIT_PREFIXED_IPV4_TCP ("tcp4:127.0.0.1:", "127.0.0.1", ""),
151 1.1 christos
152 1.1 christos /* Prefixed "udp4:" IPv4, host and port present. */
153 1.1 christos INIT_PREFIXED_IPV4_UDP ("udp4:127.0.0.1:1234", "127.0.0.1", "1234"),
154 1.1 christos /* Prefixed "udp4:" IPv4, only port. */
155 1.1 christos INIT_PREFIXED_IPV4_UDP ("udp4::1234", "localhost", "1234"),
156 1.1 christos /* Prefixed "udp4:" IPv4, only host. */
157 1.1 christos INIT_PREFIXED_IPV4_UDP ("udp4:127.0.0.1", "127.0.0.1", ""),
158 1.1 christos /* Prefixed "udp4:" IPv4, missing port. */
159 1.1 christos INIT_PREFIXED_IPV4_UDP ("udp4:127.0.0.1:", "127.0.0.1", ""),
160 1.1 christos
161 1.1 christos
162 1.1 christos /* Prefixed "tcp6:" IPv6, host and port present. */
163 1.1 christos INIT_PREFIXED_IPV6_TCP ("tcp6:::1:1234", "::1", "1234"),
164 1.1 christos /* Prefixed "tcp6:" IPv6, only port. */
165 1.1 christos INIT_PREFIXED_IPV6_TCP ("tcp6::1234", "localhost", "1234"),
166 1.1 christos /* Prefixed "tcp6:" IPv6, only host. */
167 1.1 christos //INIT_PREFIXED_IPV6_TCP ("tcp6:::1", "::1", ""),
168 1.1 christos /* Prefixed "tcp6:" IPv6, missing port. */
169 1.1 christos INIT_PREFIXED_IPV6_TCP ("tcp6:::1:", "::1", ""),
170 1.1 christos
171 1.1 christos /* Prefixed "udp6:" IPv6, host and port present. */
172 1.1 christos INIT_PREFIXED_IPV6_UDP ("udp6:::1:1234", "::1", "1234"),
173 1.1 christos /* Prefixed "udp6:" IPv6, only port. */
174 1.1 christos INIT_PREFIXED_IPV6_UDP ("udp6::1234", "localhost", "1234"),
175 1.1 christos /* Prefixed "udp6:" IPv6, only host. */
176 1.1 christos //INIT_PREFIXED_IPV6_UDP ("udp6:::1", "::1", ""),
177 1.1 christos /* Prefixed "udp6:" IPv6, missing port. */
178 1.1 christos INIT_PREFIXED_IPV6_UDP ("udp6:::1:", "::1", ""),
179 1.1 christos
180 1.1 christos /* Prefixed "tcp6:" IPv6 with brackets, host and port present. */
181 1.1 christos INIT_PREFIXED_IPV6_TCP ("tcp6:[::1]:1234", "::1", "1234"),
182 1.1 christos /* Prefixed "tcp6:" IPv6 with brackets, only host. */
183 1.1 christos INIT_PREFIXED_IPV6_TCP ("tcp6:[::1]", "::1", ""),
184 1.1 christos /* Prefixed "tcp6:" IPv6 with brackets, missing port. */
185 1.1 christos INIT_PREFIXED_IPV6_TCP ("tcp6:[::1]:", "::1", ""),
186 1.1 christos
187 1.1 christos /* Prefixed "udp6:" IPv6 with brackets, host and port present. */
188 1.1 christos INIT_PREFIXED_IPV6_UDP ("udp6:[::1]:1234", "::1", "1234"),
189 1.1 christos /* Prefixed "udp6:" IPv6 with brackets, only host. */
190 1.1 christos INIT_PREFIXED_IPV6_UDP ("udp6:[::1]", "::1", ""),
191 1.1 christos /* Prefixed "udp6:" IPv6 with brackets, missing port. */
192 1.1 christos INIT_PREFIXED_IPV6_UDP ("udp6:[::1]:", "::1", ""),
193 1.1 christos
194 1.1 christos
195 1.1 christos /* Bogus addresses. */
196 1.1 christos INIT_BOGUS_ENTRY ("tcp6:[::1]123:44"),
197 1.1 christos INIT_BOGUS_ENTRY ("[::1"),
198 1.1 christos INIT_BOGUS_ENTRY ("tcp6:::1]:"),
199 1.1 christos };
200 1.1 christos
201 1.1 christos /* Test a connection spec C. */
202 1.1 christos
203 1.1 christos static void
204 1.1 christos test_conn (const parse_conn_test &c)
205 1.1 christos {
206 1.1 christos struct addrinfo hint;
207 1.1 christos parsed_connection_spec ret;
208 1.1 christos
209 1.1 christos memset (&hint, 0, sizeof (hint));
210 1.1 christos
211 1.1.1.2 christos try
212 1.1 christos {
213 1.1 christos ret = parse_connection_spec (c.connspec, &hint);
214 1.1 christos }
215 1.1.1.2 christos catch (const gdb_exception_error &ex)
216 1.1 christos {
217 1.1 christos /* If we caught an error, we should check if this connection
218 1.1 christos spec was supposed to fail. */
219 1.1 christos SELF_CHECK (c.should_fail);
220 1.1 christos return;
221 1.1 christos }
222 1.1 christos
223 1.1 christos SELF_CHECK (!c.should_fail);
224 1.1 christos SELF_CHECK (ret.host_str == c.expected_result.host_str);
225 1.1 christos SELF_CHECK (ret.port_str == c.expected_result.port_str);
226 1.1 christos SELF_CHECK (hint.ai_family == c.exp_ai_family);
227 1.1 christos SELF_CHECK (hint.ai_socktype == c.exp_ai_socktype);
228 1.1 christos SELF_CHECK (hint.ai_protocol == c.exp_ai_protocol);
229 1.1 christos }
230 1.1 christos
231 1.1 christos /* Run the tests associated with parsing connection specs. */
232 1.1 christos
233 1.1 christos static void
234 1.1 christos run_tests ()
235 1.1 christos {
236 1.1 christos for (const parse_conn_test &c : conn_test)
237 1.1 christos test_conn (c);
238 1.1 christos }
239 1.1 christos } /* namespace parse_connection_spec_tests */
240 1.1 christos } /* namespace selftests */
241 1.1 christos
242 1.1.1.2 christos void _initialize_parse_connection_spec_selftests ();
243 1.1 christos void
244 1.1 christos _initialize_parse_connection_spec_selftests ()
245 1.1 christos {
246 1.1 christos selftests::register_test ("parse_connection_spec",
247 1.1 christos selftests::parse_connection_spec_tests::run_tests);
248 1.1 christos }
249