GCC Code Coverage Report


Directory: src/gate/
File: src/gate/net/nameresolvers.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 54 70 77.1%
Functions: 5 5 100.0%
Branches: 16 31 51.6%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/net/nameresolvers.h"
30 #include "gate/results.h"
31 #include "gate/net/sockets.h"
32 #include "gate/regexpressions.h"
33
34 #define GATE_NET_NAMERSOLVERS_ADDRINFO_IMPL 1
35
36
37 1 gate_bool_t gate_net_is_ipv4_address(gate_string_t const* ipv4text)
38 {
39 static gate_string_t const ipv4_pattern = GATE_STRING_INIT_STATIC("^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$");
40 static gate_regex_pattern_t rx;
41 static gate_bool_t is_init = false;
42 gate_result_t result;
43 gate_size_t dummy;
44
45
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!is_init)
46 {
47 1 result = gate_regex_init(&rx, &ipv4_pattern);
48
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (GATE_FAILED(result))
49 {
50 gate_socket_ip4address_t ip4;
51 result = gate_socket_parse_ip4(ipv4text, &ip4);
52 return GATE_SUCCEEDED(result);
53 }
54 else
55 {
56 1 is_init = true;
57 }
58 }
59 1 result = gate_regex_match(&rx, ipv4text, &dummy, &dummy);
60 1 return GATE_SUCCEEDED(result);
61 }
62
63 1 gate_bool_t gate_net_is_ipv6_address(gate_string_t const* ipv6text)
64 {
65 gate_socket_ip6address_t ip6;
66 1 gate_result_t result = gate_socket_parse_ip6(ipv6text, &ip6);
67 1 return GATE_SUCCEEDED(result);
68 }
69
70
71
72 #if defined(GATE_NET_NAMERSOLVERS_ADDRINFO_IMPL)
73
74 static gate_bool_t network_init();
75 static gate_bool_t network_uninit();
76
77 #include "gate/platforms.h"
78 #include "gate/net/platform/socket_api.h"
79
80 static gate_net_platform_socket_api_t api;
81
82 5 static gate_bool_t network_init()
83 {
84 5 gate_result_t result = gate_socket_init();
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (GATE_FAILED(result))
86 {
87 return false;
88 }
89 5 result = gate_socket_api_load(&api);
90
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (GATE_FAILED(result))
91 {
92 return false;
93 }
94 5 result = gate_socket_session_init();
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (GATE_FAILED(result))
96 {
97 return false;
98 }
99
100 5 return true;
101 }
102 5 static gate_bool_t network_uninit()
103 {
104 5 gate_result_t result = gate_socket_session_uninit();
105 5 return GATE_SUCCEEDED(result);
106 }
107
108
109
110
111 5 gate_result_t gate_net_resolve_host(gate_string_t const* hostname,
112 gate_int16_t family,
113 gate_socket_endpoint_t* endpoints,
114 gate_size_t* endpoints_length)
115 {
116 5 gate_result_t ret = GATE_RESULT_FAILED;
117 gate_result_t result;
118 struct addrinfo hints;
119 5 struct addrinfo* ptr_infos = NULL;
120 struct addrinfo const* ptr_info;
121 char host[512];
122 int errcode;
123 5 gate_size_t ep_used = 0;
124 5 gate_bool_t net_uninit_required = false;
125
126 do
127 {
128
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
5 if (!endpoints || !endpoints_length)
129 {
130 ret = GATE_RESULT_INVALIDARG;
131 break;
132 }
133
134 5 net_uninit_required = network_init();
135
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!net_uninit_required)
136 {
137 ret = GATE_RESULT_NOTAVAILABLE;
138 break;
139 }
140
141 5 gate_string_to_buffer(hostname, host, sizeof(host));
142 5 gate_mem_clear(&hints, sizeof(hints));
143
144 5 hints.ai_family = PF_UNSPEC;
145
1/3
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
5 switch (family)
146 {
147 5 case GATE_SOCKET_FAMILY_INET4:
148 {
149 5 hints.ai_family = AF_INET;
150 5 break;
151 }
152 case GATE_SOCKET_FAMILY_INET6:
153 {
154 hints.ai_family = AF_INET6;
155 break;
156 }
157 }
158 5 hints.ai_socktype = SOCK_STREAM;
159 5 hints.ai_protocol = 0;
160 5 hints.ai_flags = AI_CANONNAME;
161 5 errcode = api.sock_getaddrinfo(host, NULL, &hints, &ptr_infos);
162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (errcode != 0)
163 {
164 ret = GATE_RESULT_FAILED;
165 break;
166 }
167
168 5 ret = GATE_RESULT_OK;
169
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 5 times.
11 for (ptr_info = ptr_infos; ptr_info != NULL; ptr_info = ptr_info->ai_next)
170 {
171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ep_used >= *endpoints_length)
172 {
173 /* there are more results than space available */
174 ret = GATE_RESULT_OK_PARTIAL;
175 break;
176 }
177
178 6 result = gate_socket_load_endpoint(ptr_info->ai_addr, endpoints);
179
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (GATE_SUCCEEDED(result))
180 {
181 6 ++endpoints;
182 6 ++ep_used;
183 }
184 }
185 5 *endpoints_length = ep_used;
186
187 } while (0);
188
189
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (ptr_infos != NULL)
190 {
191 5 api.sock_freeaddrinfo(ptr_infos);
192 }
193
194
195
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (net_uninit_required)
196 {
197 5 network_uninit();
198 }
199
200 5 return ret;
201 }
202
203 #endif
204