WHATSNEW: Add release notes for Samba 4.16.10.
[Samba.git] / ctdb / tests / src / protocol_util_test.c
blob4ffe58c680c4261829e166ec3283b5f795ffec8a
1 /*
2 protocol utilities tests
4 Copyright (C) Martin Schwenke 2016
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.
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.
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/>.
20 #include "replace.h"
21 #include "system/network.h"
23 #include <assert.h>
25 #include "protocol/protocol_basic.c"
26 #include "protocol/protocol_types.c"
27 #include "protocol/protocol_util.c"
30 * Test parsing of IPs, conversion to string
33 static void test_sock_addr_to_string(const char *ip, bool with_port)
35 ctdb_sock_addr sa;
36 const char *s;
37 int ret;
39 ret = ctdb_sock_addr_from_string(ip, &sa, with_port);
40 assert(ret == 0);
41 s = ctdb_sock_addr_to_string(NULL, &sa, with_port);
42 assert(strcmp(ip, s) == 0);
43 talloc_free(discard_const(s));
46 static void test_sock_addr_from_string_bad(const char *ip, bool with_port)
48 ctdb_sock_addr sa;
49 int ret;
51 ret = ctdb_sock_addr_from_string(ip, &sa, with_port);
52 assert(ret == EINVAL);
55 static void test_sock_addr_from_string_memcmp(const char *ip1,
56 const char* ip2)
58 ctdb_sock_addr sa1, sa2;
59 int ret;
61 ret = ctdb_sock_addr_from_string(ip1, &sa1, false);
62 assert(ret == 0);
63 ret = ctdb_sock_addr_from_string(ip2, &sa2, false);
64 assert(ret == 0);
65 ret = memcmp(&sa1, &sa2, sizeof(ctdb_sock_addr));
66 assert(ret == 0);
69 static void test_sock_addr_cmp(const char *ip1, const char *ip2,
70 bool with_port, int res)
72 ctdb_sock_addr sa1, sa2;
73 int ret;
75 ret = ctdb_sock_addr_from_string(ip1, &sa1, with_port);
76 assert(ret == 0);
77 ret = ctdb_sock_addr_from_string(ip2, &sa2, with_port);
78 assert(ret == 0);
79 ret = ctdb_sock_addr_cmp(&sa1, &sa2);
80 if (ret < 0) {
81 ret = -1;
82 } else if (ret > 0) {
83 ret = 1;
86 assert(ret == res);
90 * Test parsing of IP/mask, conversion to string
93 static void test_sock_addr_mask_from_string(const char *ip_mask)
95 ctdb_sock_addr sa;
96 unsigned mask;
97 const char *s, *t;
98 int ret;
100 ret = ctdb_sock_addr_mask_from_string(ip_mask, &sa, &mask);
101 assert(ret == 0);
102 s = ctdb_sock_addr_to_string(NULL, &sa, false);
103 assert(s != NULL);
104 t = talloc_asprintf(s, "%s/%u", s, mask);
105 assert(strcmp(ip_mask, t) == 0);
106 talloc_free(discard_const(s));
109 static void test_sock_addr_mask_from_string_bad(const char *ip_mask)
111 ctdb_sock_addr sa;
112 unsigned mask;
113 int ret;
115 ret = ctdb_sock_addr_mask_from_string(ip_mask, &sa, &mask);
116 assert(ret == EINVAL);
120 * Test parsing of connection, conversion to string
123 static void test_connection_to_string(const char *conn_str)
125 TALLOC_CTX *tmp_ctx;
126 struct ctdb_connection conn;
127 const char *s, *r;
128 int ret;
130 tmp_ctx = talloc_new(NULL);
131 assert(tmp_ctx != NULL);
134 * Test non-reversed parse and render
137 ret = ctdb_connection_from_string(conn_str, false, &conn);
138 assert(ret == 0);
140 s = ctdb_connection_to_string(tmp_ctx, &conn, false);
141 assert(s != NULL);
142 ret = strcmp(conn_str, s);
143 assert(ret == 0);
145 talloc_free(discard_const(s));
148 * Reversed render
150 r = ctdb_connection_to_string(tmp_ctx, &conn, true);
151 assert(r != NULL);
152 ret = strcmp(conn_str, r);
153 assert(ret != 0);
156 * Reversed parse with forward render
158 ret = ctdb_connection_from_string(conn_str, true, &conn);
159 assert(ret == 0);
161 s = ctdb_connection_to_string(tmp_ctx, &conn, false);
162 assert(s != NULL);
163 ret = strcmp(r, s);
164 assert(ret == 0);
166 talloc_free(discard_const(s));
169 * Reversed parse and render
171 ret = ctdb_connection_from_string(conn_str, true, &conn);
172 assert(ret == 0);
174 s = ctdb_connection_to_string(tmp_ctx, &conn, true);
175 assert(s != NULL);
176 ret = strcmp(conn_str, s);
177 assert(ret == 0);
179 talloc_free(tmp_ctx);
182 static void test_connection_from_string_bad(const char *conn_str)
184 struct ctdb_connection conn;
185 int ret;
187 ret = ctdb_connection_from_string(conn_str, false, &conn);
188 assert(ret == EINVAL);
192 * Test connection list utilities
195 static void test_connection_list_read(const char *s1, const char *s2)
197 TALLOC_CTX *tmp_ctx;
198 int pipefd[2];
199 pid_t pid;
200 struct ctdb_connection_list *conn_list = NULL;
201 const char *t;
202 int ret;
204 tmp_ctx = talloc_new(NULL);
205 assert(tmp_ctx != NULL);
207 ret = pipe(pipefd);
208 assert(ret == 0);
210 pid = fork();
211 assert(pid != -1);
213 if (pid == 0) {
214 close(pipefd[0]);
216 ret = dup2(pipefd[1], STDOUT_FILENO);
217 assert(ret != -1);
219 close(pipefd[1]);
221 printf("%s", s1);
222 fflush(stdout);
224 exit(0);
227 close(pipefd[1]);
229 ret = ctdb_connection_list_read(tmp_ctx, pipefd[0], false, &conn_list);
230 assert(ret == 0);
232 close(pipefd[0]);
234 ret = ctdb_connection_list_sort(conn_list);
235 assert(ret == 0);
237 t = ctdb_connection_list_to_string(tmp_ctx, conn_list, false);
238 assert(t != NULL);
239 ret = strcmp(t, s2);
240 assert(ret == 0);
242 talloc_free(tmp_ctx);
245 static void test_connection_list_read_bad(const char *s1)
247 TALLOC_CTX *tmp_ctx;
248 int pipefd[2];
249 pid_t pid;
250 struct ctdb_connection_list *conn_list = NULL;
251 int ret;
253 tmp_ctx = talloc_new(NULL);
254 assert(tmp_ctx != NULL);
256 ret = pipe(pipefd);
257 assert(ret == 0);
259 pid = fork();
260 assert(pid != -1);
262 if (pid == 0) {
263 close(pipefd[0]);
265 ret = dup2(pipefd[1], STDOUT_FILENO);
266 assert(ret != -1);
268 close(pipefd[1]);
270 printf("%s", s1);
271 fflush(stdout);
273 exit(0);
276 close(pipefd[1]);
278 ret = ctdb_connection_list_read(tmp_ctx, pipefd[0], false, &conn_list);
279 assert(ret == EINVAL);
281 close(pipefd[0]);
283 talloc_free(tmp_ctx);
287 * Use macros for these to make them easy to concatenate
290 #define CONN4 \
292 127.0.0.1:12345 127.0.0.2:54321\n\
293 127.0.0.2:12345 127.0.0.1:54322\n\
294 127.0.0.1:12346 127.0.0.2:54323\n\
295 127.0.0.2:12345 127.0.0.1:54324\n\
296 127.0.0.1:12345 127.0.0.2:54325\n\
299 #define CONN4_SORT \
301 127.0.0.1:12345 127.0.0.2:54321\n\
302 127.0.0.1:12345 127.0.0.2:54325\n\
303 127.0.0.1:12346 127.0.0.2:54323\n\
304 127.0.0.2:12345 127.0.0.1:54322\n\
305 127.0.0.2:12345 127.0.0.1:54324\n\
308 #define CONN6 \
310 [fe80::6af7:28ff:fefa:d136]:12345 [fe80::6af7:28ff:fefa:d137]:54321\n\
311 [fe80::6af7:28ff:fefa:d138]:12345 [fe80::6af7:28ff:fefa:d137]:54322\n\
312 [fe80::6af7:28ff:fefa:d136]:12346 [fe80::6af7:28ff:fefa:d137]:54323\n\
313 [fe80::6af7:28ff:fefa:d132]:12345 [fe80::6af7:28ff:fefa:d137]:54324\n\
314 [fe80::6af7:28ff:fefa:d136]:12345 [fe80::6af7:28ff:fefa:d137]:54325\n\
317 #define CONN6_SORT \
319 [fe80::6af7:28ff:fefa:d132]:12345 [fe80::6af7:28ff:fefa:d137]:54324\n\
320 [fe80::6af7:28ff:fefa:d136]:12345 [fe80::6af7:28ff:fefa:d137]:54321\n\
321 [fe80::6af7:28ff:fefa:d136]:12345 [fe80::6af7:28ff:fefa:d137]:54325\n\
322 [fe80::6af7:28ff:fefa:d136]:12346 [fe80::6af7:28ff:fefa:d137]:54323\n\
323 [fe80::6af7:28ff:fefa:d138]:12345 [fe80::6af7:28ff:fefa:d137]:54322\n\
326 int main(int argc, char *argv[])
328 test_sock_addr_to_string("0.0.0.0", false);
329 test_sock_addr_to_string("127.0.0.1", false);
330 test_sock_addr_to_string("::1", false);
331 test_sock_addr_to_string("192.168.2.1", false);
332 test_sock_addr_to_string("fe80::6af7:28ff:fefa:d136", false);
334 test_sock_addr_to_string("0.0.0.0:0", true);
335 test_sock_addr_to_string("127.0.0.1:123", true);
336 test_sock_addr_to_string("[::1]:234", true);
337 test_sock_addr_to_string("192.168.2.1:123", true);
338 test_sock_addr_to_string("[fe80::6af7:28ff:fefa:d136]:234", true);
340 test_sock_addr_from_string_bad("0.0.0", false);
341 test_sock_addr_from_string_bad("0.0.0:0", true);
342 test_sock_addr_from_string_bad("fe80::6af7:28ff:fefa:d136", true);
343 test_sock_addr_from_string_bad("junk", false);
344 test_sock_addr_from_string_bad("0.0.0.0:0 trailing junk", true);
346 test_sock_addr_from_string_memcmp("127.0.0.1", "127.0.0.1");
347 test_sock_addr_from_string_memcmp("fe80::6af7:28ff:fefa:d136",
348 "fe80::6af7:28ff:fefa:d136");
349 test_sock_addr_from_string_memcmp("::ffff:192.0.2.128", "192.0.2.128");
351 test_sock_addr_cmp("127.0.0.1", "127.0.0.1" , false, 0);
352 test_sock_addr_cmp("127.0.0.1", "127.0.0.2" , false, -1);
353 test_sock_addr_cmp("127.0.0.2", "127.0.0.1" , false, 1);
354 test_sock_addr_cmp("127.0.1.2", "127.0.2.1" , false, -1);
355 test_sock_addr_cmp("127.0.2.1", "127.0.1.2" , false, 1);
356 test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136", "127.0.1.2" , false, 1);
357 test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136",
358 "fe80::6af7:28ff:fefa:d136" , false, 0);
359 test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136",
360 "fe80::6af7:28ff:fefa:d137" , false, -1);
361 test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136",
362 "fe80:0000:0000:0000:6af7:28ff:fefa:d136" ,
363 false, 0);
364 test_sock_addr_cmp("::ffff:192.0.2.128", "192.0.2.128", false, 0);
366 test_sock_addr_cmp("127.0.0.1:123", "127.0.0.1:124" , true, -1);
367 test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136:123",
368 "fe80::6af7:28ff:fefa:d136:122" , true, 1);
371 * Confirm equivalence of IPv6 sockets with and without
372 * square-brackets
374 test_sock_addr_cmp("[::1]:234", "::1:234", true, 0);
375 test_sock_addr_cmp("[fe80::6af7:28ff:fefa:d136]:234",
376 "fe80::6af7:28ff:fefa:d136:234",
377 true,
379 /* Check IPv4-mapped IPv6 addresses */
380 test_sock_addr_cmp("::ffff:172.16.0.27:977",
381 "172.16.0.27:977",
382 true,
384 test_sock_addr_cmp("[::ffff:172.16.0.27]:977",
385 "172.16.0.27:977",
386 true,
389 test_sock_addr_mask_from_string("127.0.0.1/8");
390 test_sock_addr_mask_from_string("::1/128");
391 test_sock_addr_mask_from_string("fe80::6af7:28ff:fefa:d136/64");
392 test_sock_addr_mask_from_string_bad("127.0.0.1");
394 test_connection_to_string("127.0.0.1:12345 127.0.0.2:54321");
395 test_connection_to_string("[fe80::6af7:28ff:fefa:d137]:12345 "
396 "[fe80::6af7:28ff:fefa:d138]:54321");
398 test_connection_from_string_bad("127.0.0.1:12345 127.0.0.2:");
399 test_connection_from_string_bad("127.0.0.1:12345");
400 test_connection_from_string_bad("127.0.0.1:12345 "
401 "[fe80::6af7:28ff:fefa:d136]:122");
402 test_connection_from_string_bad("Junk!");
403 test_connection_from_string_bad("More junk");
405 test_connection_list_read(CONN4, CONN4_SORT);
406 test_connection_list_read(CONN6, CONN6_SORT);
407 test_connection_list_read(CONN4 CONN6, CONN4_SORT CONN6_SORT);
408 test_connection_list_read(CONN4 "# Comment\n\n# Comment\n" CONN6,
409 CONN4_SORT CONN6_SORT);
411 test_connection_list_read_bad(CONN4 "# Comment\n\nJunk!!!\n" CONN6);
412 test_connection_list_read_bad(CONN4
413 "# Comment\n\n127.0.0.1: 127.0.0.1:124\n"
414 CONN6);
416 return 0;