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