2 Unix SMB/CIFS implementation.
4 WINS replication testing
6 Copyright (C) Andrew Tridgell 2005
7 Copyright (C) Stefan Metzmacher 2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "libcli/wrepl/winsrepl.h"
26 #include "lib/events/events.h"
27 #include "lib/socket/socket.h"
28 #include "libcli/resolve/resolve.h"
29 #include "system/network.h"
30 #include "netif/netif.h"
31 #include "librpc/gen_ndr/ndr_nbt.h"
32 #include "torture/torture.h"
34 #define CHECK_STATUS(status, correct) do { \
35 if (!NT_STATUS_EQUAL(status, correct)) { \
36 printf("(%s) Incorrect status %s - should be %s\n", \
37 __location__, nt_errstr(status), nt_errstr(correct)); \
42 #define CHECK_VALUE(v, correct) do { \
43 if ((v) != (correct)) { \
44 printf("(%s) Incorrect value %s=%d - should be %d\n", \
45 __location__, #v, v, correct); \
50 #define CHECK_VALUE_UINT64(v, correct) do { \
51 if ((v) != (correct)) { \
52 printf("(%s) Incorrect value %s=%llu - should be %llu\n", \
53 __location__, #v, (long long)v, (long long)correct); \
58 #define CHECK_VALUE_STRING(v, correct) do { \
59 if ( ((!v) && (correct)) || \
60 ((v) && (!correct)) || \
61 ((v) && (correct) && strcmp(v,correct) != 0)) { \
62 printf("(%s) Incorrect value %s='%s' - should be '%s'\n", \
63 __location__, #v, v, correct); \
68 #define _NBT_NAME(n,t,s) {\
74 static const char *wrepl_name_type_string(enum wrepl_name_type type)
77 case WREPL_TYPE_UNIQUE: return "UNIQUE";
78 case WREPL_TYPE_GROUP: return "GROUP";
79 case WREPL_TYPE_SGROUP: return "SGROUP";
80 case WREPL_TYPE_MHOMED: return "MHOMED";
82 return "UNKNOWN_TYPE";
85 static const char *wrepl_name_state_string(enum wrepl_name_state state)
88 case WREPL_STATE_ACTIVE: return "ACTIVE";
89 case WREPL_STATE_RELEASED: return "RELEASED";
90 case WREPL_STATE_TOMBSTONE: return "TOMBSTONE";
91 case WREPL_STATE_RESERVED: return "RESERVED";
93 return "UNKNOWN_STATE";
97 test how assoc_ctx's are only usable on the connection
100 static BOOL test_assoc_ctx1(TALLOC_CTX *mem_ctx, const char *address)
103 struct wrepl_request *req;
104 struct wrepl_socket *wrepl_socket1;
105 struct wrepl_associate associate1;
106 struct wrepl_socket *wrepl_socket2;
107 struct wrepl_associate associate2;
108 struct wrepl_pull_table pull_table;
109 struct wrepl_packet packet;
110 struct wrepl_send_ctrl ctrl;
111 struct wrepl_packet *rep_packet;
112 struct wrepl_associate_stop assoc_stop;
115 if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
116 printf("winsrepl: cross connection assoc_ctx usage disabled - enable dangerous tests to use\n");
120 printf("Test if assoc_ctx is only valid on the conection it was created on\n");
122 wrepl_socket1 = wrepl_socket_init(mem_ctx, NULL);
123 wrepl_socket2 = wrepl_socket_init(mem_ctx, NULL);
125 printf("Setup 2 wrepl connections\n");
126 status = wrepl_connect(wrepl_socket1, NULL, address);
127 CHECK_STATUS(status, NT_STATUS_OK);
129 status = wrepl_connect(wrepl_socket2, NULL, address);
130 CHECK_STATUS(status, NT_STATUS_OK);
132 printf("Send a start association request (conn1)\n");
133 status = wrepl_associate(wrepl_socket1, &associate1);
134 CHECK_STATUS(status, NT_STATUS_OK);
136 printf("association context (conn1): 0x%x\n", associate1.out.assoc_ctx);
138 printf("Send a start association request (conn2)\n");
139 status = wrepl_associate(wrepl_socket2, &associate2);
140 CHECK_STATUS(status, NT_STATUS_OK);
142 printf("association context (conn2): 0x%x\n", associate2.out.assoc_ctx);
144 printf("Send a replication table query, with assoc 1 (conn2), the anwser should be on conn1\n");
146 packet.opcode = WREPL_OPCODE_BITS;
147 packet.assoc_ctx = associate1.out.assoc_ctx;
148 packet.mess_type = WREPL_REPLICATION;
149 packet.message.replication.command = WREPL_REPL_TABLE_QUERY;
151 ctrl.send_only = True;
152 req = wrepl_request_send(wrepl_socket2, &packet, &ctrl);
153 status = wrepl_request_recv(req, mem_ctx, &rep_packet);
154 CHECK_STATUS(status, NT_STATUS_OK);
156 printf("Send a association request (conn2), to make sure the last request was ignored\n");
157 status = wrepl_associate(wrepl_socket2, &associate2);
158 CHECK_STATUS(status, NT_STATUS_OK);
160 printf("Send a replication table query, with invalid assoc (conn1), receive answer from conn2\n");
161 pull_table.in.assoc_ctx = 0;
162 req = wrepl_pull_table_send(wrepl_socket1, &pull_table);
163 status = wrepl_request_recv(req, mem_ctx, &rep_packet);
164 CHECK_STATUS(status, NT_STATUS_OK);
166 printf("Send a association request (conn1), to make sure the last request was handled correct\n");
167 status = wrepl_associate(wrepl_socket1, &associate2);
168 CHECK_STATUS(status, NT_STATUS_OK);
170 assoc_stop.in.assoc_ctx = associate1.out.assoc_ctx;
171 assoc_stop.in.reason = 4;
172 printf("Send a association stop request (conn1), reson: %u\n", assoc_stop.in.reason);
173 status = wrepl_associate_stop(wrepl_socket1, &assoc_stop);
174 CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
176 assoc_stop.in.assoc_ctx = associate2.out.assoc_ctx;
177 assoc_stop.in.reason = 0;
178 printf("Send a association stop request (conn2), reson: %u\n", assoc_stop.in.reason);
179 status = wrepl_associate_stop(wrepl_socket2, &assoc_stop);
180 CHECK_STATUS(status, NT_STATUS_OK);
183 printf("Close 2 wrepl connections\n");
184 talloc_free(wrepl_socket1);
185 talloc_free(wrepl_socket2);
190 test if we always get back the same assoc_ctx
192 static BOOL test_assoc_ctx2(TALLOC_CTX *mem_ctx, const char *address)
195 struct wrepl_socket *wrepl_socket;
196 struct wrepl_associate associate;
200 printf("Test if we always get back the same assoc_ctx\n");
202 wrepl_socket = wrepl_socket_init(mem_ctx, NULL);
204 printf("Setup wrepl connections\n");
205 status = wrepl_connect(wrepl_socket, NULL, address);
206 CHECK_STATUS(status, NT_STATUS_OK);
209 printf("Send 1st start association request\n");
210 status = wrepl_associate(wrepl_socket, &associate);
211 CHECK_STATUS(status, NT_STATUS_OK);
212 assoc_ctx1 = associate.out.assoc_ctx;
213 printf("1st association context: 0x%x\n", associate.out.assoc_ctx);
215 printf("Send 2nd start association request\n");
216 status = wrepl_associate(wrepl_socket, &associate);
217 CHECK_VALUE(associate.out.assoc_ctx, assoc_ctx1);
218 CHECK_STATUS(status, NT_STATUS_OK);
219 printf("2nd association context: 0x%x\n", associate.out.assoc_ctx);
221 printf("Send 3rd start association request\n");
222 status = wrepl_associate(wrepl_socket, &associate);
223 CHECK_VALUE(associate.out.assoc_ctx, assoc_ctx1);
224 CHECK_STATUS(status, NT_STATUS_OK);
225 printf("3rd association context: 0x%x\n", associate.out.assoc_ctx);
228 printf("Close wrepl connections\n");
229 talloc_free(wrepl_socket);
235 display a replication entry
237 static void display_entry(TALLOC_CTX *mem_ctx, struct wrepl_name *name)
241 printf("%s\n", nbt_name_string(mem_ctx, &name->name));
242 printf("\tTYPE:%u STATE:%u NODE:%u STATIC:%u VERSION_ID: %llu\n",
243 name->type, name->state, name->node, name->is_static, (long long)name->version_id);
244 printf("\tRAW_FLAGS: 0x%08X OWNER: %-15s\n",
245 name->raw_flags, name->owner);
246 for (i=0;i<name->num_addresses;i++) {
247 printf("\tADDR: %-15s OWNER: %-15s\n",
248 name->addresses[i].address, name->addresses[i].owner);
253 test a full replication dump from a WINS server
255 static BOOL test_wins_replication(TALLOC_CTX *mem_ctx, const char *address)
258 struct wrepl_socket *wrepl_socket;
261 struct wrepl_associate associate;
262 struct wrepl_pull_table pull_table;
263 struct wrepl_pull_names pull_names;
265 printf("Test one pull replication cycle\n");
267 wrepl_socket = wrepl_socket_init(mem_ctx, NULL);
269 printf("Setup wrepl connections\n");
270 status = wrepl_connect(wrepl_socket, NULL, address);
271 CHECK_STATUS(status, NT_STATUS_OK);
273 printf("Send a start association request\n");
275 status = wrepl_associate(wrepl_socket, &associate);
276 CHECK_STATUS(status, NT_STATUS_OK);
278 printf("association context: 0x%x\n", associate.out.assoc_ctx);
280 printf("Send a replication table query\n");
281 pull_table.in.assoc_ctx = associate.out.assoc_ctx;
283 status = wrepl_pull_table(wrepl_socket, mem_ctx, &pull_table);
284 if (NT_STATUS_EQUAL(NT_STATUS_NETWORK_ACCESS_DENIED,status)) {
285 struct wrepl_packet packet;
286 struct wrepl_request *req;
289 packet.opcode = WREPL_OPCODE_BITS;
290 packet.assoc_ctx = associate.out.assoc_ctx;
291 packet.mess_type = WREPL_STOP_ASSOCIATION;
292 packet.message.stop.reason = 0;
294 req = wrepl_request_send(wrepl_socket, &packet, NULL);
297 printf("failed - We are not a valid pull partner for the server\n");
301 CHECK_STATUS(status, NT_STATUS_OK);
303 printf("Found %d replication partners\n", pull_table.out.num_partners);
305 for (i=0;i<pull_table.out.num_partners;i++) {
306 struct wrepl_wins_owner *partner = &pull_table.out.partners[i];
307 printf("%s max_version=%6llu min_version=%6llu type=%d\n",
309 (long long)partner->max_version,
310 (long long)partner->min_version,
313 pull_names.in.assoc_ctx = associate.out.assoc_ctx;
314 pull_names.in.partner = *partner;
316 status = wrepl_pull_names(wrepl_socket, mem_ctx, &pull_names);
317 CHECK_STATUS(status, NT_STATUS_OK);
319 printf("Received %d names\n", pull_names.out.num_names);
321 for (j=0;j<pull_names.out.num_names;j++) {
322 display_entry(mem_ctx, &pull_names.out.names[j]);
327 printf("Close wrepl connections\n");
328 talloc_free(wrepl_socket);
332 struct test_wrepl_conflict_conn {
334 struct wrepl_socket *pull;
337 #define TEST_OWNER_A_ADDRESS "127.65.65.1"
338 #define TEST_ADDRESS_A_PREFIX "127.0.65"
339 #define TEST_OWNER_B_ADDRESS "127.66.66.1"
340 #define TEST_ADDRESS_B_PREFIX "127.0.66"
341 #define TEST_OWNER_X_ADDRESS "127.88.88.1"
342 #define TEST_ADDRESS_X_PREFIX "127.0.88"
344 struct wrepl_wins_owner a, b, c, x;
346 struct socket_address *myaddr;
347 struct socket_address *myaddr2;
348 struct nbt_name_socket *nbtsock;
349 struct nbt_name_socket *nbtsock2;
351 struct nbt_name_socket *nbtsock_srv;
352 struct nbt_name_socket *nbtsock_srv2;
354 uint32_t addresses_best_num;
355 struct wrepl_ip *addresses_best;
357 uint32_t addresses_best2_num;
358 struct wrepl_ip *addresses_best2;
360 uint32_t addresses_all_num;
361 struct wrepl_ip *addresses_all;
363 uint32_t addresses_mhomed_num;
364 struct wrepl_ip *addresses_mhomed;
367 static const struct wrepl_ip addresses_A_1[] = {
369 .owner = TEST_OWNER_A_ADDRESS,
370 .ip = TEST_ADDRESS_A_PREFIX".1"
373 static const struct wrepl_ip addresses_A_2[] = {
375 .owner = TEST_OWNER_A_ADDRESS,
376 .ip = TEST_ADDRESS_A_PREFIX".2"
379 static const struct wrepl_ip addresses_A_3_4[] = {
381 .owner = TEST_OWNER_A_ADDRESS,
382 .ip = TEST_ADDRESS_A_PREFIX".3"
385 .owner = TEST_OWNER_A_ADDRESS,
386 .ip = TEST_ADDRESS_A_PREFIX".4"
389 static const struct wrepl_ip addresses_A_3_4_X_3_4[] = {
391 .owner = TEST_OWNER_A_ADDRESS,
392 .ip = TEST_ADDRESS_A_PREFIX".3"
395 .owner = TEST_OWNER_A_ADDRESS,
396 .ip = TEST_ADDRESS_A_PREFIX".4"
399 .owner = TEST_OWNER_X_ADDRESS,
400 .ip = TEST_ADDRESS_X_PREFIX".3"
403 .owner = TEST_OWNER_X_ADDRESS,
404 .ip = TEST_ADDRESS_X_PREFIX".4"
407 static const struct wrepl_ip addresses_A_3_4_B_3_4[] = {
409 .owner = TEST_OWNER_A_ADDRESS,
410 .ip = TEST_ADDRESS_A_PREFIX".3"
413 .owner = TEST_OWNER_A_ADDRESS,
414 .ip = TEST_ADDRESS_A_PREFIX".4"
417 .owner = TEST_OWNER_B_ADDRESS,
418 .ip = TEST_ADDRESS_B_PREFIX".3"
421 .owner = TEST_OWNER_B_ADDRESS,
422 .ip = TEST_ADDRESS_B_PREFIX".4"
425 static const struct wrepl_ip addresses_A_3_4_OWNER_B[] = {
427 .owner = TEST_OWNER_B_ADDRESS,
428 .ip = TEST_ADDRESS_A_PREFIX".3"
431 .owner = TEST_OWNER_B_ADDRESS,
432 .ip = TEST_ADDRESS_A_PREFIX".4"
435 static const struct wrepl_ip addresses_A_3_4_X_3_4_OWNER_B[] = {
437 .owner = TEST_OWNER_B_ADDRESS,
438 .ip = TEST_ADDRESS_A_PREFIX".3"
441 .owner = TEST_OWNER_B_ADDRESS,
442 .ip = TEST_ADDRESS_A_PREFIX".4"
445 .owner = TEST_OWNER_B_ADDRESS,
446 .ip = TEST_ADDRESS_X_PREFIX".3"
449 .owner = TEST_OWNER_B_ADDRESS,
450 .ip = TEST_ADDRESS_X_PREFIX".4"
454 static const struct wrepl_ip addresses_A_3_4_X_1_2[] = {
456 .owner = TEST_OWNER_A_ADDRESS,
457 .ip = TEST_ADDRESS_A_PREFIX".3"
460 .owner = TEST_OWNER_A_ADDRESS,
461 .ip = TEST_ADDRESS_A_PREFIX".4"
464 .owner = TEST_OWNER_X_ADDRESS,
465 .ip = TEST_ADDRESS_X_PREFIX".1"
468 .owner = TEST_OWNER_X_ADDRESS,
469 .ip = TEST_ADDRESS_X_PREFIX".2"
473 static const struct wrepl_ip addresses_B_1[] = {
475 .owner = TEST_OWNER_B_ADDRESS,
476 .ip = TEST_ADDRESS_B_PREFIX".1"
479 static const struct wrepl_ip addresses_B_2[] = {
481 .owner = TEST_OWNER_B_ADDRESS,
482 .ip = TEST_ADDRESS_B_PREFIX".2"
485 static const struct wrepl_ip addresses_B_3_4[] = {
487 .owner = TEST_OWNER_B_ADDRESS,
488 .ip = TEST_ADDRESS_B_PREFIX".3"
491 .owner = TEST_OWNER_B_ADDRESS,
492 .ip = TEST_ADDRESS_B_PREFIX".4"
495 static const struct wrepl_ip addresses_B_3_4_X_3_4[] = {
497 .owner = TEST_OWNER_B_ADDRESS,
498 .ip = TEST_ADDRESS_B_PREFIX".3"
501 .owner = TEST_OWNER_B_ADDRESS,
502 .ip = TEST_ADDRESS_B_PREFIX".4"
505 .owner = TEST_OWNER_X_ADDRESS,
506 .ip = TEST_ADDRESS_X_PREFIX".3"
509 .owner = TEST_OWNER_X_ADDRESS,
510 .ip = TEST_ADDRESS_X_PREFIX".4"
513 static const struct wrepl_ip addresses_B_3_4_X_1_2[] = {
515 .owner = TEST_OWNER_B_ADDRESS,
516 .ip = TEST_ADDRESS_B_PREFIX".3"
519 .owner = TEST_OWNER_B_ADDRESS,
520 .ip = TEST_ADDRESS_B_PREFIX".4"
523 .owner = TEST_OWNER_X_ADDRESS,
524 .ip = TEST_ADDRESS_X_PREFIX".1"
527 .owner = TEST_OWNER_X_ADDRESS,
528 .ip = TEST_ADDRESS_X_PREFIX".2"
532 static const struct wrepl_ip addresses_X_1_2[] = {
534 .owner = TEST_OWNER_X_ADDRESS,
535 .ip = TEST_ADDRESS_X_PREFIX".1"
538 .owner = TEST_OWNER_X_ADDRESS,
539 .ip = TEST_ADDRESS_X_PREFIX".2"
542 static const struct wrepl_ip addresses_X_3_4[] = {
544 .owner = TEST_OWNER_X_ADDRESS,
545 .ip = TEST_ADDRESS_X_PREFIX".3"
548 .owner = TEST_OWNER_X_ADDRESS,
549 .ip = TEST_ADDRESS_X_PREFIX".4"
553 static struct test_wrepl_conflict_conn *test_create_conflict_ctx(TALLOC_CTX *mem_ctx,
556 struct test_wrepl_conflict_conn *ctx;
557 struct wrepl_associate associate;
558 struct wrepl_pull_table pull_table;
559 struct socket_address *nbt_srv_addr;
563 ctx = talloc_zero(mem_ctx, struct test_wrepl_conflict_conn);
564 if (!ctx) return NULL;
566 ctx->address = address;
567 ctx->pull = wrepl_socket_init(ctx, NULL);
568 if (!ctx->pull) return NULL;
570 printf("Setup wrepl conflict pull connection\n");
571 status = wrepl_connect(ctx->pull, NULL, ctx->address);
572 if (!NT_STATUS_IS_OK(status)) return NULL;
574 status = wrepl_associate(ctx->pull, &associate);
575 if (!NT_STATUS_IS_OK(status)) return NULL;
577 ctx->pull_assoc = associate.out.assoc_ctx;
579 ctx->a.address = TEST_OWNER_A_ADDRESS;
580 ctx->a.max_version = 0;
581 ctx->a.min_version = 0;
584 ctx->b.address = TEST_OWNER_B_ADDRESS;
585 ctx->b.max_version = 0;
586 ctx->b.min_version = 0;
589 ctx->x.address = TEST_OWNER_X_ADDRESS;
590 ctx->x.max_version = 0;
591 ctx->x.min_version = 0;
594 ctx->c.address = address;
595 ctx->c.max_version = 0;
596 ctx->c.min_version = 0;
599 pull_table.in.assoc_ctx = ctx->pull_assoc;
600 status = wrepl_pull_table(ctx->pull, ctx->pull, &pull_table);
601 if (!NT_STATUS_IS_OK(status)) return NULL;
603 for (i=0; i < pull_table.out.num_partners; i++) {
604 if (strcmp(TEST_OWNER_A_ADDRESS,pull_table.out.partners[i].address)==0) {
605 ctx->a.max_version = pull_table.out.partners[i].max_version;
606 ctx->a.min_version = pull_table.out.partners[i].min_version;
608 if (strcmp(TEST_OWNER_B_ADDRESS,pull_table.out.partners[i].address)==0) {
609 ctx->b.max_version = pull_table.out.partners[i].max_version;
610 ctx->b.min_version = pull_table.out.partners[i].min_version;
612 if (strcmp(TEST_OWNER_X_ADDRESS,pull_table.out.partners[i].address)==0) {
613 ctx->x.max_version = pull_table.out.partners[i].max_version;
614 ctx->x.min_version = pull_table.out.partners[i].min_version;
616 if (strcmp(address,pull_table.out.partners[i].address)==0) {
617 ctx->c.max_version = pull_table.out.partners[i].max_version;
618 ctx->c.min_version = pull_table.out.partners[i].min_version;
622 talloc_free(pull_table.out.partners);
624 ctx->nbtsock = nbt_name_socket_init(ctx, NULL);
625 if (!ctx->nbtsock) return NULL;
627 ctx->myaddr = socket_address_from_strings(mem_ctx, ctx->nbtsock->sock->backend_name, iface_best_ip(address), 0);
628 if (!ctx->myaddr) return NULL;
630 for (i = 0; i < iface_count(); i++) {
631 if (strcmp(ctx->myaddr->addr, iface_n_ip(i)) == 0) continue;
632 ctx->myaddr2 = socket_address_from_strings(mem_ctx, ctx->nbtsock->sock->backend_name, iface_n_ip(i), 0);
633 if (!ctx->myaddr2) return NULL;
637 status = socket_listen(ctx->nbtsock->sock, ctx->myaddr, 0, 0);
638 if (!NT_STATUS_IS_OK(status)) return NULL;
640 ctx->nbtsock_srv = nbt_name_socket_init(ctx, NULL);
641 if (!ctx->nbtsock_srv) return NULL;
643 /* Make a port 137 version of ctx->myaddr */
644 nbt_srv_addr = socket_address_from_strings(mem_ctx, ctx->nbtsock_srv->sock->backend_name, ctx->myaddr->addr, lp_nbt_port());
645 if (!nbt_srv_addr) return NULL;
647 /* And if possible, bind to it. This won't work unless we are root or in sockewrapper */
648 status = socket_listen(ctx->nbtsock_srv->sock, nbt_srv_addr, 0, 0);
649 talloc_free(nbt_srv_addr);
650 if (!NT_STATUS_IS_OK(status)) {
651 /* this isn't fatal */
652 talloc_free(ctx->nbtsock_srv);
653 ctx->nbtsock_srv = NULL;
656 if (ctx->myaddr2 && ctx->nbtsock_srv) {
657 ctx->nbtsock2 = nbt_name_socket_init(ctx, NULL);
658 if (!ctx->nbtsock2) return NULL;
660 status = socket_listen(ctx->nbtsock2->sock, ctx->myaddr2, 0, 0);
661 if (!NT_STATUS_IS_OK(status)) return NULL;
663 ctx->nbtsock_srv2 = nbt_name_socket_init(ctx, ctx->nbtsock_srv->event_ctx);
664 if (!ctx->nbtsock_srv2) return NULL;
666 /* Make a port 137 version of ctx->myaddr2 */
667 nbt_srv_addr = socket_address_from_strings(mem_ctx,
668 ctx->nbtsock_srv->sock->backend_name,
669 ctx->myaddr2->addr, lp_nbt_port());
670 if (!nbt_srv_addr) return NULL;
672 /* And if possible, bind to it. This won't work unless we are root or in sockewrapper */
673 status = socket_listen(ctx->nbtsock_srv2->sock, ctx->myaddr2, 0, 0);
674 talloc_free(nbt_srv_addr);
675 if (!NT_STATUS_IS_OK(status)) {
676 /* this isn't fatal */
677 talloc_free(ctx->nbtsock_srv2);
678 ctx->nbtsock_srv2 = NULL;
682 ctx->addresses_best_num = 1;
683 ctx->addresses_best = talloc_array(ctx, struct wrepl_ip, ctx->addresses_best_num);
684 if (!ctx->addresses_best) return NULL;
685 ctx->addresses_best[0].owner = ctx->b.address;
686 ctx->addresses_best[0].ip = ctx->myaddr->addr;
688 ctx->addresses_all_num = iface_count();
689 ctx->addresses_all = talloc_array(ctx, struct wrepl_ip, ctx->addresses_all_num);
690 if (!ctx->addresses_all) return NULL;
691 for (i=0; i < ctx->addresses_all_num; i++) {
692 ctx->addresses_all[i].owner = ctx->b.address;
693 ctx->addresses_all[i].ip = talloc_strdup(ctx->addresses_all, iface_n_ip(i));
694 if (!ctx->addresses_all[i].ip) return NULL;
697 if (ctx->nbtsock_srv2) {
698 ctx->addresses_best2_num = 1;
699 ctx->addresses_best2 = talloc_array(ctx, struct wrepl_ip, ctx->addresses_best2_num);
700 if (!ctx->addresses_best2) return NULL;
701 ctx->addresses_best2[0].owner = ctx->b.address;
702 ctx->addresses_best2[0].ip = ctx->myaddr2->addr;
704 ctx->addresses_mhomed_num = 2;
705 ctx->addresses_mhomed = talloc_array(ctx, struct wrepl_ip, ctx->addresses_mhomed_num);
706 if (!ctx->addresses_mhomed) return NULL;
707 ctx->addresses_mhomed[0].owner = ctx->b.address;
708 ctx->addresses_mhomed[0].ip = ctx->myaddr->addr;
709 ctx->addresses_mhomed[1].owner = ctx->b.address;
710 ctx->addresses_mhomed[1].ip = ctx->myaddr2->addr;
716 static BOOL test_wrepl_update_one(struct test_wrepl_conflict_conn *ctx,
717 const struct wrepl_wins_owner *owner,
718 const struct wrepl_wins_name *name)
721 struct wrepl_socket *wrepl_socket;
722 struct wrepl_associate associate;
723 struct wrepl_packet update_packet, repl_send;
724 struct wrepl_table *update;
725 struct wrepl_wins_owner wrepl_wins_owners[1];
726 struct wrepl_packet *repl_recv;
727 struct wrepl_wins_owner *send_request;
728 struct wrepl_send_reply *send_reply;
729 struct wrepl_wins_name wrepl_wins_names[1];
733 wrepl_socket = wrepl_socket_init(ctx, NULL);
735 status = wrepl_connect(wrepl_socket, NULL, ctx->address);
736 CHECK_STATUS(status, NT_STATUS_OK);
738 status = wrepl_associate(wrepl_socket, &associate);
739 CHECK_STATUS(status, NT_STATUS_OK);
740 assoc_ctx = associate.out.assoc_ctx;
742 /* now send a WREPL_REPL_UPDATE message */
743 ZERO_STRUCT(update_packet);
744 update_packet.opcode = WREPL_OPCODE_BITS;
745 update_packet.assoc_ctx = assoc_ctx;
746 update_packet.mess_type = WREPL_REPLICATION;
747 update_packet.message.replication.command = WREPL_REPL_UPDATE;
748 update = &update_packet.message.replication.info.table;
750 update->partner_count = ARRAY_SIZE(wrepl_wins_owners);
751 update->partners = wrepl_wins_owners;
752 update->initiator = "0.0.0.0";
754 wrepl_wins_owners[0] = *owner;
756 status = wrepl_request(wrepl_socket, wrepl_socket,
757 &update_packet, &repl_recv);
758 CHECK_STATUS(status, NT_STATUS_OK);
759 CHECK_VALUE(repl_recv->mess_type, WREPL_REPLICATION);
760 CHECK_VALUE(repl_recv->message.replication.command, WREPL_REPL_SEND_REQUEST);
761 send_request = &repl_recv->message.replication.info.owner;
763 ZERO_STRUCT(repl_send);
764 repl_send.opcode = WREPL_OPCODE_BITS;
765 repl_send.assoc_ctx = assoc_ctx;
766 repl_send.mess_type = WREPL_REPLICATION;
767 repl_send.message.replication.command = WREPL_REPL_SEND_REPLY;
768 send_reply = &repl_send.message.replication.info.reply;
770 send_reply->num_names = ARRAY_SIZE(wrepl_wins_names);
771 send_reply->names = wrepl_wins_names;
773 wrepl_wins_names[0] = *name;
775 status = wrepl_request(wrepl_socket, wrepl_socket,
776 &repl_send, &repl_recv);
777 CHECK_STATUS(status, NT_STATUS_OK);
778 CHECK_VALUE(repl_recv->mess_type, WREPL_STOP_ASSOCIATION);
779 CHECK_VALUE(repl_recv->message.stop.reason, 0);
782 talloc_free(wrepl_socket);
786 static BOOL test_wrepl_is_applied(struct test_wrepl_conflict_conn *ctx,
787 const struct wrepl_wins_owner *owner,
788 const struct wrepl_wins_name *name,
793 struct wrepl_pull_names pull_names;
794 struct wrepl_name *names;
796 pull_names.in.assoc_ctx = ctx->pull_assoc;
797 pull_names.in.partner = *owner;
798 pull_names.in.partner.min_version = pull_names.in.partner.max_version;
800 status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
801 CHECK_STATUS(status, NT_STATUS_OK);
802 CHECK_VALUE(pull_names.out.num_names, (expected?1:0));
804 names = pull_names.out.names;
807 uint32_t flags = WREPL_NAME_FLAGS(names[0].type,
811 CHECK_VALUE(names[0].name.type, name->name->type);
812 CHECK_VALUE_STRING(names[0].name.name, name->name->name);
813 CHECK_VALUE_STRING(names[0].name.scope, name->name->scope);
814 CHECK_VALUE(flags, name->flags);
815 CHECK_VALUE_UINT64(names[0].version_id, name->id);
818 CHECK_VALUE(names[0].num_addresses,
819 name->addresses.addresses.num_ips);
821 CHECK_VALUE(names[0].num_addresses, 1);
822 CHECK_VALUE_STRING(names[0].addresses[0].address,
827 talloc_free(pull_names.out.names);
831 static BOOL test_wrepl_mhomed_merged(struct test_wrepl_conflict_conn *ctx,
832 const struct wrepl_wins_owner *owner1,
833 uint32_t num_ips1, const struct wrepl_ip *ips1,
834 const struct wrepl_wins_owner *owner2,
835 uint32_t num_ips2, const struct wrepl_ip *ips2,
836 const struct wrepl_wins_name *name2)
840 struct wrepl_pull_names pull_names;
841 struct wrepl_name *names;
844 uint32_t num_ips = num_ips1 + num_ips2;
846 for (i = 0; i < num_ips2; i++) {
847 for (j = 0; j < num_ips1; j++) {
848 if (strcmp(ips2[i].ip,ips1[j].ip) == 0) {
855 pull_names.in.assoc_ctx = ctx->pull_assoc;
856 pull_names.in.partner = *owner2;
857 pull_names.in.partner.min_version = pull_names.in.partner.max_version;
859 status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
860 CHECK_STATUS(status, NT_STATUS_OK);
861 CHECK_VALUE(pull_names.out.num_names, 1);
863 names = pull_names.out.names;
865 flags = WREPL_NAME_FLAGS(names[0].type,
869 CHECK_VALUE(names[0].name.type, name2->name->type);
870 CHECK_VALUE_STRING(names[0].name.name, name2->name->name);
871 CHECK_VALUE_STRING(names[0].name.scope, name2->name->scope);
872 CHECK_VALUE(flags, name2->flags | WREPL_TYPE_MHOMED);
873 CHECK_VALUE_UINT64(names[0].version_id, name2->id);
875 CHECK_VALUE(names[0].num_addresses, num_ips);
877 for (i = 0; i < names[0].num_addresses; i++) {
878 const char *addr = names[0].addresses[i].address;
879 const char *owner = names[0].addresses[i].owner;
882 for (j = 0; j < num_ips2; j++) {
883 if (strcmp(addr, ips2[j].ip) == 0) {
885 CHECK_VALUE_STRING(owner, owner2->address);
892 for (j = 0; j < num_ips1; j++) {
893 if (strcmp(addr, ips1[j].ip) == 0) {
895 CHECK_VALUE_STRING(owner, owner1->address);
902 CHECK_VALUE_STRING(addr, "not found in address list");
905 talloc_free(pull_names.out.names);
909 static BOOL test_wrepl_sgroup_merged(struct test_wrepl_conflict_conn *ctx,
910 struct wrepl_wins_owner *merge_owner,
911 struct wrepl_wins_owner *owner1,
912 uint32_t num_ips1, const struct wrepl_ip *ips1,
913 struct wrepl_wins_owner *owner2,
914 uint32_t num_ips2, const struct wrepl_ip *ips2,
915 const struct wrepl_wins_name *name2)
919 struct wrepl_pull_names pull_names;
920 struct wrepl_name *names;
921 struct wrepl_name *name = NULL;
924 uint32_t num_ips = num_ips1 + num_ips2;
927 merge_owner = &ctx->c;
930 for (i = 0; i < num_ips1; i++) {
931 if (owner1 != &ctx->c && strcmp(ips1[i].owner,owner2->address) == 0) {
935 for (j = 0; j < num_ips2; j++) {
936 if (strcmp(ips1[i].ip,ips2[j].ip) == 0) {
944 pull_names.in.assoc_ctx = ctx->pull_assoc;
945 pull_names.in.partner = *merge_owner;
946 pull_names.in.partner.min_version = pull_names.in.partner.max_version;
947 pull_names.in.partner.max_version = 0;
949 status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
950 CHECK_STATUS(status, NT_STATUS_OK);
952 names = pull_names.out.names;
954 for (i = 0; i < pull_names.out.num_names; i++) {
955 if (names[i].name.type != name2->name->type) continue;
956 if (!names[i].name.name) continue;
957 if (strcmp(names[i].name.name, name2->name->name) != 0) continue;
958 if (names[i].name.scope) continue;
963 if (pull_names.out.num_names > 0) {
964 merge_owner->max_version = names[pull_names.out.num_names-1].version_id;
968 printf("%s: Name '%s' not found\n", __location__, nbt_name_string(ctx, name2->name));
972 flags = WREPL_NAME_FLAGS(name->type,
976 CHECK_VALUE(name->name.type, name2->name->type);
977 CHECK_VALUE_STRING(name->name.name, name2->name->name);
978 CHECK_VALUE_STRING(name->name.scope, name2->name->scope);
979 CHECK_VALUE(flags, name2->flags);
981 CHECK_VALUE(name->num_addresses, num_ips);
983 for (i = 0; i < name->num_addresses; i++) {
984 const char *addr = name->addresses[i].address;
985 const char *owner = name->addresses[i].owner;
988 for (j = 0; j < num_ips2; j++) {
989 if (strcmp(addr, ips2[j].ip) == 0) {
991 CHECK_VALUE_STRING(owner, ips2[j].owner);
998 for (j = 0; j < num_ips1; j++) {
999 if (strcmp(addr, ips1[j].ip) == 0) {
1001 if (owner1 == &ctx->c) {
1002 CHECK_VALUE_STRING(owner, owner1->address);
1004 CHECK_VALUE_STRING(owner, ips1[j].owner);
1010 if (found) continue;
1012 CHECK_VALUE_STRING(addr, "not found in address list");
1015 talloc_free(pull_names.out.names);
1019 static BOOL test_conflict_same_owner(struct test_wrepl_conflict_conn *ctx)
1022 struct nbt_name name;
1023 struct wrepl_wins_name wins_name1;
1024 struct wrepl_wins_name wins_name2;
1025 struct wrepl_wins_name *wins_name_tmp;
1026 struct wrepl_wins_name *wins_name_last;
1027 struct wrepl_wins_name *wins_name_cur;
1029 uint8_t types[] = { 0x00, 0x1C };
1031 enum wrepl_name_type type;
1032 enum wrepl_name_state state;
1033 enum wrepl_name_node node;
1036 const struct wrepl_ip *ips;
1039 .type = WREPL_TYPE_GROUP,
1040 .state = WREPL_STATE_ACTIVE,
1041 .node = WREPL_NODE_B,
1043 .num_ips = ARRAY_SIZE(addresses_A_1),
1044 .ips = addresses_A_1,
1046 .type = WREPL_TYPE_UNIQUE,
1047 .state = WREPL_STATE_ACTIVE,
1048 .node = WREPL_NODE_B,
1050 .num_ips = ARRAY_SIZE(addresses_A_1),
1051 .ips = addresses_A_1,
1053 .type = WREPL_TYPE_UNIQUE,
1054 .state = WREPL_STATE_ACTIVE,
1055 .node = WREPL_NODE_B,
1057 .num_ips = ARRAY_SIZE(addresses_A_2),
1058 .ips = addresses_A_2,
1060 .type = WREPL_TYPE_UNIQUE,
1061 .state = WREPL_STATE_ACTIVE,
1062 .node = WREPL_NODE_B,
1064 .num_ips = ARRAY_SIZE(addresses_A_1),
1065 .ips = addresses_A_1,
1067 .type = WREPL_TYPE_UNIQUE,
1068 .state = WREPL_STATE_ACTIVE,
1069 .node = WREPL_NODE_B,
1071 .num_ips = ARRAY_SIZE(addresses_A_2),
1072 .ips = addresses_A_2,
1074 .type = WREPL_TYPE_SGROUP,
1075 .state = WREPL_STATE_TOMBSTONE,
1076 .node = WREPL_NODE_B,
1078 .num_ips = ARRAY_SIZE(addresses_A_2),
1079 .ips = addresses_A_2,
1081 .type = WREPL_TYPE_MHOMED,
1082 .state = WREPL_STATE_TOMBSTONE,
1083 .node = WREPL_NODE_B,
1085 .num_ips = ARRAY_SIZE(addresses_A_1),
1086 .ips = addresses_A_1,
1088 .type = WREPL_TYPE_MHOMED,
1089 .state = WREPL_STATE_RELEASED,
1090 .node = WREPL_NODE_B,
1092 .num_ips = ARRAY_SIZE(addresses_A_2),
1093 .ips = addresses_A_2,
1095 .type = WREPL_TYPE_SGROUP,
1096 .state = WREPL_STATE_ACTIVE,
1097 .node = WREPL_NODE_B,
1099 .num_ips = ARRAY_SIZE(addresses_A_1),
1100 .ips = addresses_A_1,
1102 .type = WREPL_TYPE_SGROUP,
1103 .state = WREPL_STATE_ACTIVE,
1104 .node = WREPL_NODE_B,
1106 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1107 .ips = addresses_A_3_4,
1109 .type = WREPL_TYPE_SGROUP,
1110 .state = WREPL_STATE_TOMBSTONE,
1111 .node = WREPL_NODE_B,
1113 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1114 .ips = addresses_B_3_4,
1116 /* the last one should always be a unique,tomstone record! */
1117 .type = WREPL_TYPE_UNIQUE,
1118 .state = WREPL_STATE_TOMBSTONE,
1119 .node = WREPL_NODE_B,
1121 .num_ips = ARRAY_SIZE(addresses_A_1),
1122 .ips = addresses_A_1,
1126 name.name = "_SAME_OWNER_A";
1130 wins_name_tmp = NULL;
1131 wins_name_last = &wins_name2;
1132 wins_name_cur = &wins_name1;
1134 for (j=0; ret && j < ARRAY_SIZE(types); j++) {
1135 name.type = types[j];
1136 printf("Test Replica Conflicts with same owner[%s] for %s\n",
1137 nbt_name_string(ctx, &name), ctx->a.address);
1139 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
1140 wins_name_tmp = wins_name_last;
1141 wins_name_last = wins_name_cur;
1142 wins_name_cur = wins_name_tmp;
1145 printf("%s,%s%s vs. %s,%s%s with %s ip(s) => %s\n",
1146 wrepl_name_type_string(records[i-1].type),
1147 wrepl_name_state_string(records[i-1].state),
1148 (records[i-1].is_static?",static":""),
1149 wrepl_name_type_string(records[i].type),
1150 wrepl_name_state_string(records[i].state),
1151 (records[i].is_static?",static":""),
1152 (records[i-1].ips==records[i].ips?"same":"different"),
1156 wins_name_cur->name = &name;
1157 wins_name_cur->flags = WREPL_NAME_FLAGS(records[i].type,
1160 records[i].is_static);
1161 wins_name_cur->id = ++ctx->a.max_version;
1162 if (wins_name_cur->flags & 2) {
1163 wins_name_cur->addresses.addresses.num_ips = records[i].num_ips;
1164 wins_name_cur->addresses.addresses.ips = discard_const(records[i].ips);
1166 wins_name_cur->addresses.ip = records[i].ips[0].ip;
1168 wins_name_cur->unknown = "255.255.255.255";
1170 ret &= test_wrepl_update_one(ctx, &ctx->a,wins_name_cur);
1171 if (records[i].state == WREPL_STATE_RELEASED) {
1172 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_last, False);
1173 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_cur, False);
1175 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_cur, True);
1178 /* the first one is a cleanup run */
1179 if (!ret && i == 0) ret = True;
1182 printf("conflict handled wrong or record[%u]: %s\n", i, __location__);
1190 static BOOL test_conflict_different_owner(struct test_wrepl_conflict_conn *ctx)
1193 struct wrepl_wins_name wins_name1;
1194 struct wrepl_wins_name wins_name2;
1195 struct wrepl_wins_name *wins_name_r1;
1196 struct wrepl_wins_name *wins_name_r2;
1199 const char *line; /* just better debugging */
1200 struct nbt_name name;
1201 const char *comment;
1202 BOOL extra; /* not the worst case, this is an extra test */
1205 struct wrepl_wins_owner *owner;
1206 enum wrepl_name_type type;
1207 enum wrepl_name_state state;
1208 enum wrepl_name_node node;
1211 const struct wrepl_ip *ips;
1212 BOOL apply_expected;
1214 struct wrepl_wins_owner *merge_owner;
1215 BOOL sgroup_cleanup;
1219 * NOTE: the first record and the last applied one
1220 * needs to be from the same owner,
1221 * to not conflict in the next smbtorture run!!!
1224 .line = __location__,
1225 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1229 .type = WREPL_TYPE_UNIQUE,
1230 .state = WREPL_STATE_TOMBSTONE,
1231 .node = WREPL_NODE_B,
1233 .num_ips = ARRAY_SIZE(addresses_B_1),
1234 .ips = addresses_B_1,
1235 .apply_expected = True /* ignored */
1239 .type = WREPL_TYPE_UNIQUE,
1240 .state = WREPL_STATE_TOMBSTONE,
1241 .node = WREPL_NODE_B,
1243 .num_ips = ARRAY_SIZE(addresses_A_1),
1244 .ips = addresses_A_1,
1245 .apply_expected = True /* ignored */
1250 * unique vs unique section
1253 * unique,active vs. unique,active
1254 * => should be replaced
1257 .line = __location__,
1258 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1261 .type = WREPL_TYPE_UNIQUE,
1262 .state = WREPL_STATE_ACTIVE,
1263 .node = WREPL_NODE_B,
1265 .num_ips = ARRAY_SIZE(addresses_A_1),
1266 .ips = addresses_A_1,
1267 .apply_expected = True
1271 .type = WREPL_TYPE_UNIQUE,
1272 .state = WREPL_STATE_ACTIVE,
1273 .node = WREPL_NODE_B,
1275 .num_ips = ARRAY_SIZE(addresses_B_1),
1276 .ips = addresses_B_1,
1277 .apply_expected = True
1282 * unique,active vs. unique,tombstone
1283 * => should NOT be replaced
1286 .line = __location__,
1287 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1290 .type = WREPL_TYPE_UNIQUE,
1291 .state = WREPL_STATE_ACTIVE,
1292 .node = WREPL_NODE_B,
1294 .num_ips = ARRAY_SIZE(addresses_B_1),
1295 .ips = addresses_B_1,
1296 .apply_expected = True
1300 .type = WREPL_TYPE_UNIQUE,
1301 .state = WREPL_STATE_TOMBSTONE,
1302 .node = WREPL_NODE_B,
1304 .num_ips = ARRAY_SIZE(addresses_B_1),
1305 .ips = addresses_B_1,
1306 .apply_expected = False
1311 * unique,released vs. unique,active
1312 * => should be replaced
1315 .line = __location__,
1316 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1319 .type = WREPL_TYPE_UNIQUE,
1320 .state = WREPL_STATE_RELEASED,
1321 .node = WREPL_NODE_B,
1323 .num_ips = ARRAY_SIZE(addresses_B_1),
1324 .ips = addresses_B_1,
1325 .apply_expected = False
1329 .type = WREPL_TYPE_UNIQUE,
1330 .state = WREPL_STATE_ACTIVE,
1331 .node = WREPL_NODE_B,
1333 .num_ips = ARRAY_SIZE(addresses_A_1),
1334 .ips = addresses_A_1,
1335 .apply_expected = True
1340 * unique,released vs. unique,tombstone
1341 * => should be replaced
1344 .line = __location__,
1345 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1348 .type = WREPL_TYPE_UNIQUE,
1349 .state = WREPL_STATE_RELEASED,
1350 .node = WREPL_NODE_B,
1352 .num_ips = ARRAY_SIZE(addresses_A_1),
1353 .ips = addresses_A_1,
1354 .apply_expected = False
1358 .type = WREPL_TYPE_UNIQUE,
1359 .state = WREPL_STATE_TOMBSTONE,
1360 .node = WREPL_NODE_B,
1362 .num_ips = ARRAY_SIZE(addresses_B_1),
1363 .ips = addresses_B_1,
1364 .apply_expected = True
1369 * unique,tombstone vs. unique,active
1370 * => should be replaced
1373 .line = __location__,
1374 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1377 .type = WREPL_TYPE_UNIQUE,
1378 .state = WREPL_STATE_TOMBSTONE,
1379 .node = WREPL_NODE_B,
1381 .num_ips = ARRAY_SIZE(addresses_B_1),
1382 .ips = addresses_B_1,
1383 .apply_expected = True
1387 .type = WREPL_TYPE_UNIQUE,
1388 .state = WREPL_STATE_ACTIVE,
1389 .node = WREPL_NODE_B,
1391 .num_ips = ARRAY_SIZE(addresses_A_1),
1392 .ips = addresses_A_1,
1393 .apply_expected = True
1398 * unique,tombstone vs. unique,tombstone
1399 * => should be replaced
1402 .line = __location__,
1403 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1406 .type = WREPL_TYPE_UNIQUE,
1407 .state = WREPL_STATE_TOMBSTONE,
1408 .node = WREPL_NODE_B,
1410 .num_ips = ARRAY_SIZE(addresses_A_1),
1411 .ips = addresses_A_1,
1412 .apply_expected = True
1416 .type = WREPL_TYPE_UNIQUE,
1417 .state = WREPL_STATE_TOMBSTONE,
1418 .node = WREPL_NODE_B,
1420 .num_ips = ARRAY_SIZE(addresses_B_1),
1421 .ips = addresses_B_1,
1422 .apply_expected = True
1428 * unique vs normal groups section,
1431 * unique,active vs. group,active
1432 * => should be replaced
1435 .line = __location__,
1436 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1439 .type = WREPL_TYPE_UNIQUE,
1440 .state = WREPL_STATE_ACTIVE,
1441 .node = WREPL_NODE_B,
1443 .num_ips = ARRAY_SIZE(addresses_B_1),
1444 .ips = addresses_B_1,
1445 .apply_expected = True
1449 .type = WREPL_TYPE_GROUP,
1450 .state = WREPL_STATE_ACTIVE,
1451 .node = WREPL_NODE_B,
1453 .num_ips = ARRAY_SIZE(addresses_A_1),
1454 .ips = addresses_A_1,
1455 .apply_expected = True
1460 * unique,active vs. group,tombstone
1461 * => should NOT be replaced
1464 .line = __location__,
1465 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1468 .type = WREPL_TYPE_UNIQUE,
1469 .state = WREPL_STATE_ACTIVE,
1470 .node = WREPL_NODE_B,
1472 .num_ips = ARRAY_SIZE(addresses_A_1),
1473 .ips = addresses_A_1,
1474 .apply_expected = True
1478 .type = WREPL_TYPE_GROUP,
1479 .state = WREPL_STATE_TOMBSTONE,
1480 .node = WREPL_NODE_B,
1482 .num_ips = ARRAY_SIZE(addresses_A_1),
1483 .ips = addresses_A_1,
1484 .apply_expected = False
1489 * unique,released vs. group,active
1490 * => should be replaced
1493 .line = __location__,
1494 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1497 .type = WREPL_TYPE_UNIQUE,
1498 .state = WREPL_STATE_RELEASED,
1499 .node = WREPL_NODE_B,
1501 .num_ips = ARRAY_SIZE(addresses_A_1),
1502 .ips = addresses_A_1,
1503 .apply_expected = False
1507 .type = WREPL_TYPE_GROUP,
1508 .state = WREPL_STATE_ACTIVE,
1509 .node = WREPL_NODE_B,
1511 .num_ips = ARRAY_SIZE(addresses_B_1),
1512 .ips = addresses_B_1,
1513 .apply_expected = True
1518 * unique,released vs. group,tombstone
1519 * => should be replaced
1522 .line = __location__,
1523 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1526 .type = WREPL_TYPE_UNIQUE,
1527 .state = WREPL_STATE_RELEASED,
1528 .node = WREPL_NODE_B,
1530 .num_ips = ARRAY_SIZE(addresses_B_1),
1531 .ips = addresses_B_1,
1532 .apply_expected = False
1536 .type = WREPL_TYPE_GROUP,
1537 .state = WREPL_STATE_TOMBSTONE,
1538 .node = WREPL_NODE_B,
1540 .num_ips = ARRAY_SIZE(addresses_A_1),
1541 .ips = addresses_A_1,
1542 .apply_expected = True
1547 * unique,tombstone vs. group,active
1548 * => should be replaced
1551 .line = __location__,
1552 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1555 .type = WREPL_TYPE_UNIQUE,
1556 .state = WREPL_STATE_TOMBSTONE,
1557 .node = WREPL_NODE_B,
1559 .num_ips = ARRAY_SIZE(addresses_A_1),
1560 .ips = addresses_A_1,
1561 .apply_expected = True
1565 .type = WREPL_TYPE_GROUP,
1566 .state = WREPL_STATE_ACTIVE,
1567 .node = WREPL_NODE_B,
1569 .num_ips = ARRAY_SIZE(addresses_B_1),
1570 .ips = addresses_B_1,
1571 .apply_expected = True
1576 * unique,tombstone vs. group,tombstone
1577 * => should be replaced
1580 .line = __location__,
1581 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1584 .type = WREPL_TYPE_UNIQUE,
1585 .state = WREPL_STATE_TOMBSTONE,
1586 .node = WREPL_NODE_B,
1588 .num_ips = ARRAY_SIZE(addresses_B_1),
1589 .ips = addresses_B_1,
1590 .apply_expected = True
1594 .type = WREPL_TYPE_GROUP,
1595 .state = WREPL_STATE_TOMBSTONE,
1596 .node = WREPL_NODE_B,
1598 .num_ips = ARRAY_SIZE(addresses_A_1),
1599 .ips = addresses_A_1,
1600 .apply_expected = True
1605 * unique vs special groups section,
1608 * unique,active vs. sgroup,active
1609 * => should NOT be replaced
1612 .line = __location__,
1613 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1616 .type = WREPL_TYPE_UNIQUE,
1617 .state = WREPL_STATE_ACTIVE,
1618 .node = WREPL_NODE_B,
1620 .num_ips = ARRAY_SIZE(addresses_A_1),
1621 .ips = addresses_A_1,
1622 .apply_expected = True
1626 .type = WREPL_TYPE_SGROUP,
1627 .state = WREPL_STATE_ACTIVE,
1628 .node = WREPL_NODE_B,
1630 .num_ips = ARRAY_SIZE(addresses_A_1),
1631 .ips = addresses_A_1,
1632 .apply_expected = False
1637 * unique,active vs. sgroup,tombstone
1638 * => should NOT be replaced
1641 .line = __location__,
1642 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1645 .type = WREPL_TYPE_UNIQUE,
1646 .state = WREPL_STATE_ACTIVE,
1647 .node = WREPL_NODE_B,
1649 .num_ips = ARRAY_SIZE(addresses_A_1),
1650 .ips = addresses_A_1,
1651 .apply_expected = True
1655 .type = WREPL_TYPE_SGROUP,
1656 .state = WREPL_STATE_TOMBSTONE,
1657 .node = WREPL_NODE_B,
1659 .num_ips = ARRAY_SIZE(addresses_A_1),
1660 .ips = addresses_A_1,
1661 .apply_expected = False
1666 * unique,released vs. sgroup,active
1667 * => should be replaced
1670 .line = __location__,
1671 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1674 .type = WREPL_TYPE_UNIQUE,
1675 .state = WREPL_STATE_RELEASED,
1676 .node = WREPL_NODE_B,
1678 .num_ips = ARRAY_SIZE(addresses_A_1),
1679 .ips = addresses_A_1,
1680 .apply_expected = False
1684 .type = WREPL_TYPE_SGROUP,
1685 .state = WREPL_STATE_ACTIVE,
1686 .node = WREPL_NODE_B,
1688 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1689 .ips = addresses_B_3_4,
1690 .apply_expected = True
1695 * unique,released vs. sgroup,tombstone
1696 * => should be replaced
1699 .line = __location__,
1700 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1703 .type = WREPL_TYPE_UNIQUE,
1704 .state = WREPL_STATE_RELEASED,
1705 .node = WREPL_NODE_B,
1707 .num_ips = ARRAY_SIZE(addresses_B_1),
1708 .ips = addresses_B_1,
1709 .apply_expected = False
1713 .type = WREPL_TYPE_SGROUP,
1714 .state = WREPL_STATE_TOMBSTONE,
1715 .node = WREPL_NODE_B,
1717 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1718 .ips = addresses_A_3_4,
1719 .apply_expected = True
1724 * unique,tombstone vs. sgroup,active
1725 * => should be replaced
1728 .line = __location__,
1729 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1732 .type = WREPL_TYPE_UNIQUE,
1733 .state = WREPL_STATE_TOMBSTONE,
1734 .node = WREPL_NODE_B,
1736 .num_ips = ARRAY_SIZE(addresses_A_1),
1737 .ips = addresses_A_1,
1738 .apply_expected = True
1742 .type = WREPL_TYPE_SGROUP,
1743 .state = WREPL_STATE_ACTIVE,
1744 .node = WREPL_NODE_B,
1746 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1747 .ips = addresses_B_3_4,
1748 .apply_expected = True
1753 * unique,tombstone vs. sgroup,tombstone
1754 * => should be replaced
1757 .line = __location__,
1758 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1761 .type = WREPL_TYPE_UNIQUE,
1762 .state = WREPL_STATE_TOMBSTONE,
1763 .node = WREPL_NODE_B,
1765 .num_ips = ARRAY_SIZE(addresses_B_1),
1766 .ips = addresses_B_1,
1767 .apply_expected = True
1771 .type = WREPL_TYPE_SGROUP,
1772 .state = WREPL_STATE_TOMBSTONE,
1773 .node = WREPL_NODE_B,
1775 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1776 .ips = addresses_A_3_4,
1777 .apply_expected = True
1782 * unique vs multi homed section,
1785 * unique,active vs. mhomed,active
1786 * => should be replaced
1789 .line = __location__,
1790 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1793 .type = WREPL_TYPE_UNIQUE,
1794 .state = WREPL_STATE_ACTIVE,
1795 .node = WREPL_NODE_B,
1797 .num_ips = ARRAY_SIZE(addresses_A_1),
1798 .ips = addresses_A_1,
1799 .apply_expected = True
1803 .type = WREPL_TYPE_MHOMED,
1804 .state = WREPL_STATE_ACTIVE,
1805 .node = WREPL_NODE_B,
1807 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1808 .ips = addresses_B_3_4,
1809 .apply_expected = True
1814 * unique,active vs. mhomed,tombstone
1815 * => should NOT be replaced
1818 .line = __location__,
1819 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1822 .type = WREPL_TYPE_UNIQUE,
1823 .state = WREPL_STATE_ACTIVE,
1824 .node = WREPL_NODE_B,
1826 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1827 .ips = addresses_B_3_4,
1828 .apply_expected = True
1832 .type = WREPL_TYPE_MHOMED,
1833 .state = WREPL_STATE_TOMBSTONE,
1834 .node = WREPL_NODE_B,
1836 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1837 .ips = addresses_B_3_4,
1838 .apply_expected = False
1843 * unique,released vs. mhomed,active
1844 * => should be replaced
1847 .line = __location__,
1848 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1851 .type = WREPL_TYPE_UNIQUE,
1852 .state = WREPL_STATE_RELEASED,
1853 .node = WREPL_NODE_B,
1855 .num_ips = ARRAY_SIZE(addresses_B_1),
1856 .ips = addresses_B_1,
1857 .apply_expected = False
1861 .type = WREPL_TYPE_MHOMED,
1862 .state = WREPL_STATE_ACTIVE,
1863 .node = WREPL_NODE_B,
1865 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1866 .ips = addresses_A_3_4,
1867 .apply_expected = True
1872 * unique,released vs. mhomed,tombstone
1873 * => should be replaced
1876 .line = __location__,
1877 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1880 .type = WREPL_TYPE_UNIQUE,
1881 .state = WREPL_STATE_RELEASED,
1882 .node = WREPL_NODE_B,
1884 .num_ips = ARRAY_SIZE(addresses_A_1),
1885 .ips = addresses_A_1,
1886 .apply_expected = False
1890 .type = WREPL_TYPE_MHOMED,
1891 .state = WREPL_STATE_TOMBSTONE,
1892 .node = WREPL_NODE_B,
1894 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1895 .ips = addresses_B_3_4,
1896 .apply_expected = True
1901 * unique,tombstone vs. mhomed,active
1902 * => should be replaced
1905 .line = __location__,
1906 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1909 .type = WREPL_TYPE_UNIQUE,
1910 .state = WREPL_STATE_TOMBSTONE,
1911 .node = WREPL_NODE_B,
1913 .num_ips = ARRAY_SIZE(addresses_B_1),
1914 .ips = addresses_B_1,
1915 .apply_expected = True
1919 .type = WREPL_TYPE_MHOMED,
1920 .state = WREPL_STATE_ACTIVE,
1921 .node = WREPL_NODE_B,
1923 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1924 .ips = addresses_A_3_4,
1925 .apply_expected = True
1930 * unique,tombstone vs. mhomed,tombstone
1931 * => should be replaced
1934 .line = __location__,
1935 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1938 .type = WREPL_TYPE_UNIQUE,
1939 .state = WREPL_STATE_TOMBSTONE,
1940 .node = WREPL_NODE_B,
1942 .num_ips = ARRAY_SIZE(addresses_A_1),
1943 .ips = addresses_A_1,
1944 .apply_expected = True
1948 .type = WREPL_TYPE_MHOMED,
1949 .state = WREPL_STATE_TOMBSTONE,
1950 .node = WREPL_NODE_B,
1952 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1953 .ips = addresses_B_3_4,
1954 .apply_expected = True
1959 * normal groups vs unique section,
1962 * group,active vs. unique,active
1963 * => should NOT be replaced
1966 .line = __location__,
1967 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1970 .type = WREPL_TYPE_GROUP,
1971 .state = WREPL_STATE_ACTIVE,
1972 .node = WREPL_NODE_B,
1974 .num_ips = ARRAY_SIZE(addresses_A_1),
1975 .ips = addresses_A_1,
1976 .apply_expected = True
1980 .type = WREPL_TYPE_UNIQUE,
1981 .state = WREPL_STATE_ACTIVE,
1982 .node = WREPL_NODE_B,
1984 .num_ips = ARRAY_SIZE(addresses_A_1),
1985 .ips = addresses_A_1,
1986 .apply_expected = False
1991 * group,active vs. unique,tombstone
1992 * => should NOT be replaced
1995 .line = __location__,
1996 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1999 .type = WREPL_TYPE_GROUP,
2000 .state = WREPL_STATE_ACTIVE,
2001 .node = WREPL_NODE_B,
2003 .num_ips = ARRAY_SIZE(addresses_A_1),
2004 .ips = addresses_A_1,
2005 .apply_expected = True
2009 .type = WREPL_TYPE_UNIQUE,
2010 .state = WREPL_STATE_TOMBSTONE,
2011 .node = WREPL_NODE_B,
2013 .num_ips = ARRAY_SIZE(addresses_A_1),
2014 .ips = addresses_A_1,
2015 .apply_expected = False
2020 * group,released vs. unique,active
2021 * => should NOT be replaced
2024 .line = __location__,
2025 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2028 .type = WREPL_TYPE_GROUP,
2029 .state = WREPL_STATE_RELEASED,
2030 .node = WREPL_NODE_B,
2032 .num_ips = ARRAY_SIZE(addresses_A_1),
2033 .ips = addresses_A_1,
2034 .apply_expected = False
2038 .type = WREPL_TYPE_UNIQUE,
2039 .state = WREPL_STATE_ACTIVE,
2040 .node = WREPL_NODE_B,
2042 .num_ips = ARRAY_SIZE(addresses_A_1),
2043 .ips = addresses_A_1,
2044 .apply_expected = False
2049 * group,released vs. unique,tombstone
2050 * => should NOT be replaced
2053 .line = __location__,
2054 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2057 .type = WREPL_TYPE_GROUP,
2058 .state = WREPL_STATE_RELEASED,
2059 .node = WREPL_NODE_B,
2061 .num_ips = ARRAY_SIZE(addresses_A_1),
2062 .ips = addresses_A_1,
2063 .apply_expected = False
2067 .type = WREPL_TYPE_UNIQUE,
2068 .state = WREPL_STATE_TOMBSTONE,
2069 .node = WREPL_NODE_B,
2071 .num_ips = ARRAY_SIZE(addresses_A_1),
2072 .ips = addresses_A_1,
2073 .apply_expected = False
2078 * group,tombstone vs. unique,active
2079 * => should NOT be replaced
2082 .line = __location__,
2083 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2086 .type = WREPL_TYPE_GROUP,
2087 .state = WREPL_STATE_TOMBSTONE,
2088 .node = WREPL_NODE_B,
2090 .num_ips = ARRAY_SIZE(addresses_A_1),
2091 .ips = addresses_A_1,
2092 .apply_expected = True
2096 .type = WREPL_TYPE_UNIQUE,
2097 .state = WREPL_STATE_ACTIVE,
2098 .node = WREPL_NODE_B,
2100 .num_ips = ARRAY_SIZE(addresses_A_1),
2101 .ips = addresses_A_1,
2102 .apply_expected = False
2107 * group,tombstone vs. unique,tombstone
2108 * => should NOT be replaced
2111 .line = __location__,
2112 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2115 .type = WREPL_TYPE_GROUP,
2116 .state = WREPL_STATE_TOMBSTONE,
2117 .node = WREPL_NODE_B,
2119 .num_ips = ARRAY_SIZE(addresses_A_1),
2120 .ips = addresses_A_1,
2121 .apply_expected = True
2125 .type = WREPL_TYPE_UNIQUE,
2126 .state = WREPL_STATE_TOMBSTONE,
2127 .node = WREPL_NODE_B,
2129 .num_ips = ARRAY_SIZE(addresses_A_1),
2130 .ips = addresses_A_1,
2131 .apply_expected = False
2136 * normal groups vs normal groups section,
2139 * group,active vs. group,active
2140 * => should NOT be replaced
2143 .line = __location__,
2144 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2147 .type = WREPL_TYPE_GROUP,
2148 .state = WREPL_STATE_ACTIVE,
2149 .node = WREPL_NODE_B,
2151 .num_ips = ARRAY_SIZE(addresses_A_1),
2152 .ips = addresses_A_1,
2153 .apply_expected = True
2157 .type = WREPL_TYPE_GROUP,
2158 .state = WREPL_STATE_ACTIVE,
2159 .node = WREPL_NODE_B,
2161 .num_ips = ARRAY_SIZE(addresses_A_1),
2162 .ips = addresses_A_1,
2163 .apply_expected = False
2168 * group,active vs. group,tombstone
2169 * => should NOT be replaced
2172 .line = __location__,
2173 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2176 .type = WREPL_TYPE_GROUP,
2177 .state = WREPL_STATE_ACTIVE,
2178 .node = WREPL_NODE_B,
2180 .num_ips = ARRAY_SIZE(addresses_A_1),
2181 .ips = addresses_A_1,
2182 .apply_expected = True
2186 .type = WREPL_TYPE_GROUP,
2187 .state = WREPL_STATE_TOMBSTONE,
2188 .node = WREPL_NODE_B,
2190 .num_ips = ARRAY_SIZE(addresses_A_1),
2191 .ips = addresses_A_1,
2192 .apply_expected = False
2197 * group,released vs. group,active
2198 * => should be replaced
2201 .line = __location__,
2202 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2205 .type = WREPL_TYPE_GROUP,
2206 .state = WREPL_STATE_RELEASED,
2207 .node = WREPL_NODE_B,
2209 .num_ips = ARRAY_SIZE(addresses_A_1),
2210 .ips = addresses_A_1,
2211 .apply_expected = False
2215 .type = WREPL_TYPE_GROUP,
2216 .state = WREPL_STATE_ACTIVE,
2217 .node = WREPL_NODE_B,
2219 .num_ips = ARRAY_SIZE(addresses_B_1),
2220 .ips = addresses_B_1,
2221 .apply_expected = True
2226 * group,released vs. group,tombstone
2227 * => should be replaced
2230 .line = __location__,
2231 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2234 .type = WREPL_TYPE_GROUP,
2235 .state = WREPL_STATE_RELEASED,
2236 .node = WREPL_NODE_B,
2238 .num_ips = ARRAY_SIZE(addresses_A_1),
2239 .ips = addresses_A_1,
2240 .apply_expected = False
2244 .type = WREPL_TYPE_GROUP,
2245 .state = WREPL_STATE_TOMBSTONE,
2246 .node = WREPL_NODE_B,
2248 .num_ips = ARRAY_SIZE(addresses_B_1),
2249 .ips = addresses_B_1,
2250 .apply_expected = True
2255 * group,tombstone vs. group,active
2256 * => should be replaced
2259 .line = __location__,
2260 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2263 .type = WREPL_TYPE_GROUP,
2264 .state = WREPL_STATE_TOMBSTONE,
2265 .node = WREPL_NODE_B,
2267 .num_ips = ARRAY_SIZE(addresses_B_1),
2268 .ips = addresses_B_1,
2269 .apply_expected = True
2273 .type = WREPL_TYPE_GROUP,
2274 .state = WREPL_STATE_ACTIVE,
2275 .node = WREPL_NODE_B,
2277 .num_ips = ARRAY_SIZE(addresses_A_1),
2278 .ips = addresses_A_1,
2279 .apply_expected = True
2284 * group,tombstone vs. group,tombstone
2285 * => should be replaced
2288 .line = __location__,
2289 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2292 .type = WREPL_TYPE_GROUP,
2293 .state = WREPL_STATE_TOMBSTONE,
2294 .node = WREPL_NODE_B,
2296 .num_ips = ARRAY_SIZE(addresses_A_1),
2297 .ips = addresses_A_1,
2298 .apply_expected = True
2302 .type = WREPL_TYPE_GROUP,
2303 .state = WREPL_STATE_TOMBSTONE,
2304 .node = WREPL_NODE_B,
2306 .num_ips = ARRAY_SIZE(addresses_B_1),
2307 .ips = addresses_B_1,
2308 .apply_expected = True
2313 * normal groups vs special groups section,
2316 * group,active vs. sgroup,active
2317 * => should NOT be replaced
2320 .line = __location__,
2321 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2324 .type = WREPL_TYPE_GROUP,
2325 .state = WREPL_STATE_ACTIVE,
2326 .node = WREPL_NODE_B,
2328 .num_ips = ARRAY_SIZE(addresses_B_1),
2329 .ips = addresses_B_1,
2330 .apply_expected = True
2334 .type = WREPL_TYPE_SGROUP,
2335 .state = WREPL_STATE_ACTIVE,
2336 .node = WREPL_NODE_B,
2338 .num_ips = ARRAY_SIZE(addresses_B_1),
2339 .ips = addresses_B_1,
2340 .apply_expected = False
2345 * group,active vs. sgroup,tombstone
2346 * => should NOT be replaced
2349 .line = __location__,
2350 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2353 .type = WREPL_TYPE_GROUP,
2354 .state = WREPL_STATE_ACTIVE,
2355 .node = WREPL_NODE_B,
2357 .num_ips = ARRAY_SIZE(addresses_B_1),
2358 .ips = addresses_B_1,
2359 .apply_expected = True
2363 .type = WREPL_TYPE_SGROUP,
2364 .state = WREPL_STATE_TOMBSTONE,
2365 .node = WREPL_NODE_B,
2367 .num_ips = ARRAY_SIZE(addresses_B_1),
2368 .ips = addresses_B_1,
2369 .apply_expected = False
2374 * group,released vs. sgroup,active
2375 * => should be replaced
2378 .line = __location__,
2379 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2382 .type = WREPL_TYPE_GROUP,
2383 .state = WREPL_STATE_RELEASED,
2384 .node = WREPL_NODE_B,
2386 .num_ips = ARRAY_SIZE(addresses_A_1),
2387 .ips = addresses_A_1,
2388 .apply_expected = False
2392 .type = WREPL_TYPE_SGROUP,
2393 .state = WREPL_STATE_ACTIVE,
2394 .node = WREPL_NODE_B,
2396 .num_ips = ARRAY_SIZE(addresses_B_1),
2397 .ips = addresses_B_1,
2398 .apply_expected = True
2403 * group,released vs. sgroup,tombstone
2404 * => should NOT be replaced
2407 .line = __location__,
2408 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2411 .type = WREPL_TYPE_GROUP,
2412 .state = WREPL_STATE_RELEASED,
2413 .node = WREPL_NODE_B,
2415 .num_ips = ARRAY_SIZE(addresses_B_1),
2416 .ips = addresses_B_1,
2417 .apply_expected = False
2421 .type = WREPL_TYPE_SGROUP,
2422 .state = WREPL_STATE_TOMBSTONE,
2423 .node = WREPL_NODE_B,
2425 .num_ips = ARRAY_SIZE(addresses_B_1),
2426 .ips = addresses_B_1,
2427 .apply_expected = False
2432 * group,tombstone vs. sgroup,active
2433 * => should be replaced
2436 .line = __location__,
2437 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2440 .type = WREPL_TYPE_GROUP,
2441 .state = WREPL_STATE_TOMBSTONE,
2442 .node = WREPL_NODE_B,
2444 .num_ips = ARRAY_SIZE(addresses_B_1),
2445 .ips = addresses_B_1,
2446 .apply_expected = True
2450 .type = WREPL_TYPE_SGROUP,
2451 .state = WREPL_STATE_ACTIVE,
2452 .node = WREPL_NODE_B,
2454 .num_ips = ARRAY_SIZE(addresses_A_1),
2455 .ips = addresses_A_1,
2456 .apply_expected = True
2461 * group,tombstone vs. sgroup,tombstone
2462 * => should be replaced
2465 .line = __location__,
2466 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2469 .type = WREPL_TYPE_GROUP,
2470 .state = WREPL_STATE_TOMBSTONE,
2471 .node = WREPL_NODE_B,
2473 .num_ips = ARRAY_SIZE(addresses_A_1),
2474 .ips = addresses_A_1,
2475 .apply_expected = True
2479 .type = WREPL_TYPE_SGROUP,
2480 .state = WREPL_STATE_TOMBSTONE,
2481 .node = WREPL_NODE_B,
2483 .num_ips = ARRAY_SIZE(addresses_B_1),
2484 .ips = addresses_B_1,
2485 .apply_expected = True
2490 * normal groups vs multi homed section,
2493 * group,active vs. mhomed,active
2494 * => should NOT be replaced
2497 .line = __location__,
2498 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2501 .type = WREPL_TYPE_GROUP,
2502 .state = WREPL_STATE_ACTIVE,
2503 .node = WREPL_NODE_B,
2505 .num_ips = ARRAY_SIZE(addresses_B_1),
2506 .ips = addresses_B_1,
2507 .apply_expected = True
2511 .type = WREPL_TYPE_MHOMED,
2512 .state = WREPL_STATE_ACTIVE,
2513 .node = WREPL_NODE_B,
2515 .num_ips = ARRAY_SIZE(addresses_B_1),
2516 .ips = addresses_B_1,
2517 .apply_expected = False
2522 * group,active vs. mhomed,tombstone
2523 * => should NOT be replaced
2526 .line = __location__,
2527 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2530 .type = WREPL_TYPE_GROUP,
2531 .state = WREPL_STATE_ACTIVE,
2532 .node = WREPL_NODE_B,
2534 .num_ips = ARRAY_SIZE(addresses_B_1),
2535 .ips = addresses_B_1,
2536 .apply_expected = True
2540 .type = WREPL_TYPE_MHOMED,
2541 .state = WREPL_STATE_TOMBSTONE,
2542 .node = WREPL_NODE_B,
2544 .num_ips = ARRAY_SIZE(addresses_B_1),
2545 .ips = addresses_B_1,
2546 .apply_expected = False
2551 * group,released vs. mhomed,active
2552 * => should NOT be replaced
2555 .line = __location__,
2556 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2559 .type = WREPL_TYPE_GROUP,
2560 .state = WREPL_STATE_RELEASED,
2561 .node = WREPL_NODE_B,
2563 .num_ips = ARRAY_SIZE(addresses_B_1),
2564 .ips = addresses_B_1,
2565 .apply_expected = False
2569 .type = WREPL_TYPE_MHOMED,
2570 .state = WREPL_STATE_ACTIVE,
2571 .node = WREPL_NODE_B,
2573 .num_ips = ARRAY_SIZE(addresses_B_1),
2574 .ips = addresses_B_1,
2575 .apply_expected = False
2580 * group,released vs. mhomed,tombstone
2581 * => should NOT be replaced
2584 .line = __location__,
2585 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2588 .type = WREPL_TYPE_GROUP,
2589 .state = WREPL_STATE_RELEASED,
2590 .node = WREPL_NODE_B,
2592 .num_ips = ARRAY_SIZE(addresses_B_1),
2593 .ips = addresses_B_1,
2594 .apply_expected = False
2598 .type = WREPL_TYPE_MHOMED,
2599 .state = WREPL_STATE_TOMBSTONE,
2600 .node = WREPL_NODE_B,
2602 .num_ips = ARRAY_SIZE(addresses_B_1),
2603 .ips = addresses_B_1,
2604 .apply_expected = False
2609 * group,tombstone vs. mhomed,active
2610 * => should be replaced
2613 .line = __location__,
2614 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2617 .type = WREPL_TYPE_GROUP,
2618 .state = WREPL_STATE_TOMBSTONE,
2619 .node = WREPL_NODE_B,
2621 .num_ips = ARRAY_SIZE(addresses_B_1),
2622 .ips = addresses_B_1,
2623 .apply_expected = True
2627 .type = WREPL_TYPE_MHOMED,
2628 .state = WREPL_STATE_ACTIVE,
2629 .node = WREPL_NODE_B,
2631 .num_ips = ARRAY_SIZE(addresses_A_1),
2632 .ips = addresses_A_1,
2633 .apply_expected = True
2638 * group,tombstone vs. mhomed,tombstone
2639 * => should be replaced
2642 .line = __location__,
2643 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2646 .type = WREPL_TYPE_GROUP,
2647 .state = WREPL_STATE_TOMBSTONE,
2648 .node = WREPL_NODE_B,
2650 .num_ips = ARRAY_SIZE(addresses_A_1),
2651 .ips = addresses_A_1,
2652 .apply_expected = True
2656 .type = WREPL_TYPE_MHOMED,
2657 .state = WREPL_STATE_TOMBSTONE,
2658 .node = WREPL_NODE_B,
2660 .num_ips = ARRAY_SIZE(addresses_B_1),
2661 .ips = addresses_B_1,
2662 .apply_expected = True
2667 * special groups vs unique section,
2670 * sgroup,active vs. unique,active
2671 * => should NOT be replaced
2674 .line = __location__,
2675 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2678 .type = WREPL_TYPE_SGROUP,
2679 .state = WREPL_STATE_ACTIVE,
2680 .node = WREPL_NODE_B,
2682 .num_ips = ARRAY_SIZE(addresses_B_1),
2683 .ips = addresses_B_1,
2684 .apply_expected = True
2688 .type = WREPL_TYPE_UNIQUE,
2689 .state = WREPL_STATE_ACTIVE,
2690 .node = WREPL_NODE_B,
2692 .num_ips = ARRAY_SIZE(addresses_B_1),
2693 .ips = addresses_B_1,
2694 .apply_expected = False
2699 * sgroup,active vs. unique,tombstone
2700 * => should NOT be replaced
2703 .line = __location__,
2704 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2707 .type = WREPL_TYPE_SGROUP,
2708 .state = WREPL_STATE_ACTIVE,
2709 .node = WREPL_NODE_B,
2711 .num_ips = ARRAY_SIZE(addresses_B_1),
2712 .ips = addresses_B_1,
2713 .apply_expected = True
2717 .type = WREPL_TYPE_UNIQUE,
2718 .state = WREPL_STATE_TOMBSTONE,
2719 .node = WREPL_NODE_B,
2721 .num_ips = ARRAY_SIZE(addresses_B_1),
2722 .ips = addresses_B_1,
2723 .apply_expected = False
2728 * sgroup,released vs. unique,active
2729 * => should be replaced
2732 .line = __location__,
2733 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2736 .type = WREPL_TYPE_SGROUP,
2737 .state = WREPL_STATE_RELEASED,
2738 .node = WREPL_NODE_B,
2740 .num_ips = ARRAY_SIZE(addresses_B_1),
2741 .ips = addresses_B_1,
2742 .apply_expected = False
2746 .type = WREPL_TYPE_UNIQUE,
2747 .state = WREPL_STATE_ACTIVE,
2748 .node = WREPL_NODE_B,
2750 .num_ips = ARRAY_SIZE(addresses_A_1),
2751 .ips = addresses_A_1,
2752 .apply_expected = True
2757 * sgroup,released vs. unique,tombstone
2758 * => should be replaced
2761 .line = __location__,
2762 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2765 .type = WREPL_TYPE_SGROUP,
2766 .state = WREPL_STATE_RELEASED,
2767 .node = WREPL_NODE_B,
2769 .num_ips = ARRAY_SIZE(addresses_A_1),
2770 .ips = addresses_A_1,
2771 .apply_expected = False
2775 .type = WREPL_TYPE_UNIQUE,
2776 .state = WREPL_STATE_TOMBSTONE,
2777 .node = WREPL_NODE_B,
2779 .num_ips = ARRAY_SIZE(addresses_B_1),
2780 .ips = addresses_B_1,
2781 .apply_expected = True
2786 * sgroup,tombstone vs. unique,active
2787 * => should be replaced
2790 .line = __location__,
2791 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2794 .type = WREPL_TYPE_SGROUP,
2795 .state = WREPL_STATE_TOMBSTONE,
2796 .node = WREPL_NODE_B,
2798 .num_ips = ARRAY_SIZE(addresses_A_1),
2799 .ips = addresses_A_1,
2800 .apply_expected = True
2804 .type = WREPL_TYPE_UNIQUE,
2805 .state = WREPL_STATE_ACTIVE,
2806 .node = WREPL_NODE_B,
2808 .num_ips = ARRAY_SIZE(addresses_B_1),
2809 .ips = addresses_B_1,
2810 .apply_expected = True
2815 * sgroup,tombstone vs. unique,tombstone
2816 * => should be replaced
2819 .line = __location__,
2820 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2823 .type = WREPL_TYPE_SGROUP,
2824 .state = WREPL_STATE_TOMBSTONE,
2825 .node = WREPL_NODE_B,
2827 .num_ips = ARRAY_SIZE(addresses_B_1),
2828 .ips = addresses_B_1,
2829 .apply_expected = True
2833 .type = WREPL_TYPE_UNIQUE,
2834 .state = WREPL_STATE_TOMBSTONE,
2835 .node = WREPL_NODE_B,
2837 .num_ips = ARRAY_SIZE(addresses_A_1),
2838 .ips = addresses_A_1,
2839 .apply_expected = True
2844 * special groups vs normal group section,
2847 * sgroup,active vs. group,active
2848 * => should NOT be replaced
2851 .line = __location__,
2852 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2855 .type = WREPL_TYPE_SGROUP,
2856 .state = WREPL_STATE_ACTIVE,
2857 .node = WREPL_NODE_B,
2859 .num_ips = ARRAY_SIZE(addresses_A_1),
2860 .ips = addresses_A_1,
2861 .apply_expected = True
2865 .type = WREPL_TYPE_GROUP,
2866 .state = WREPL_STATE_ACTIVE,
2867 .node = WREPL_NODE_B,
2869 .num_ips = ARRAY_SIZE(addresses_A_1),
2870 .ips = addresses_A_1,
2871 .apply_expected = False
2876 * sgroup,active vs. group,tombstone
2877 * => should NOT be replaced
2880 .line = __location__,
2881 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2884 .type = WREPL_TYPE_SGROUP,
2885 .state = WREPL_STATE_ACTIVE,
2886 .node = WREPL_NODE_B,
2888 .num_ips = ARRAY_SIZE(addresses_A_1),
2889 .ips = addresses_A_1,
2890 .apply_expected = True
2894 .type = WREPL_TYPE_GROUP,
2895 .state = WREPL_STATE_TOMBSTONE,
2896 .node = WREPL_NODE_B,
2898 .num_ips = ARRAY_SIZE(addresses_A_1),
2899 .ips = addresses_A_1,
2900 .apply_expected = False
2905 * sgroup,released vs. group,active
2906 * => should be replaced
2909 .line = __location__,
2910 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2913 .type = WREPL_TYPE_SGROUP,
2914 .state = WREPL_STATE_RELEASED,
2915 .node = WREPL_NODE_B,
2917 .num_ips = ARRAY_SIZE(addresses_A_1),
2918 .ips = addresses_A_1,
2919 .apply_expected = False
2923 .type = WREPL_TYPE_GROUP,
2924 .state = WREPL_STATE_ACTIVE,
2925 .node = WREPL_NODE_B,
2927 .num_ips = ARRAY_SIZE(addresses_B_1),
2928 .ips = addresses_B_1,
2929 .apply_expected = True
2934 * sgroup,released vs. group,tombstone
2935 * => should be replaced
2938 .line = __location__,
2939 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2942 .type = WREPL_TYPE_SGROUP,
2943 .state = WREPL_STATE_RELEASED,
2944 .node = WREPL_NODE_B,
2946 .num_ips = ARRAY_SIZE(addresses_B_1),
2947 .ips = addresses_B_1,
2948 .apply_expected = False
2952 .type = WREPL_TYPE_GROUP,
2953 .state = WREPL_STATE_TOMBSTONE,
2954 .node = WREPL_NODE_B,
2956 .num_ips = ARRAY_SIZE(addresses_A_1),
2957 .ips = addresses_A_1,
2958 .apply_expected = True
2963 * sgroup,tombstone vs. group,active
2964 * => should NOT be replaced
2967 .line = __location__,
2968 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2971 .type = WREPL_TYPE_SGROUP,
2972 .state = WREPL_STATE_TOMBSTONE,
2973 .node = WREPL_NODE_B,
2975 .num_ips = ARRAY_SIZE(addresses_A_1),
2976 .ips = addresses_A_1,
2977 .apply_expected = True
2981 .type = WREPL_TYPE_GROUP,
2982 .state = WREPL_STATE_ACTIVE,
2983 .node = WREPL_NODE_B,
2985 .num_ips = ARRAY_SIZE(addresses_B_1),
2986 .ips = addresses_B_1,
2987 .apply_expected = True
2992 * sgroup,tombstone vs. group,tombstone
2993 * => should NOT be replaced
2996 .line = __location__,
2997 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3000 .type = WREPL_TYPE_SGROUP,
3001 .state = WREPL_STATE_TOMBSTONE,
3002 .node = WREPL_NODE_B,
3004 .num_ips = ARRAY_SIZE(addresses_B_1),
3005 .ips = addresses_B_1,
3006 .apply_expected = True
3010 .type = WREPL_TYPE_GROUP,
3011 .state = WREPL_STATE_TOMBSTONE,
3012 .node = WREPL_NODE_B,
3014 .num_ips = ARRAY_SIZE(addresses_A_1),
3015 .ips = addresses_A_1,
3016 .apply_expected = True
3021 * special groups (not active) vs special group section,
3024 * sgroup,released vs. sgroup,active
3025 * => should be replaced
3028 .line = __location__,
3029 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3032 .type = WREPL_TYPE_SGROUP,
3033 .state = WREPL_STATE_RELEASED,
3034 .node = WREPL_NODE_B,
3036 .num_ips = ARRAY_SIZE(addresses_A_1),
3037 .ips = addresses_A_1,
3038 .apply_expected = False
3042 .type = WREPL_TYPE_SGROUP,
3043 .state = WREPL_STATE_ACTIVE,
3044 .node = WREPL_NODE_B,
3046 .num_ips = ARRAY_SIZE(addresses_B_1),
3047 .ips = addresses_B_1,
3048 .apply_expected = True
3053 * sgroup,released vs. sgroup,tombstone
3054 * => should be replaced
3057 .line = __location__,
3058 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3061 .type = WREPL_TYPE_SGROUP,
3062 .state = WREPL_STATE_RELEASED,
3063 .node = WREPL_NODE_B,
3065 .num_ips = ARRAY_SIZE(addresses_B_1),
3066 .ips = addresses_B_1,
3067 .apply_expected = False
3071 .type = WREPL_TYPE_SGROUP,
3072 .state = WREPL_STATE_TOMBSTONE,
3073 .node = WREPL_NODE_B,
3075 .num_ips = ARRAY_SIZE(addresses_A_1),
3076 .ips = addresses_A_1,
3077 .apply_expected = True
3082 * sgroup,tombstone vs. sgroup,active
3083 * => should NOT be replaced
3086 .line = __location__,
3087 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3090 .type = WREPL_TYPE_SGROUP,
3091 .state = WREPL_STATE_TOMBSTONE,
3092 .node = WREPL_NODE_B,
3094 .num_ips = ARRAY_SIZE(addresses_A_1),
3095 .ips = addresses_A_1,
3096 .apply_expected = True
3100 .type = WREPL_TYPE_SGROUP,
3101 .state = WREPL_STATE_ACTIVE,
3102 .node = WREPL_NODE_B,
3104 .num_ips = ARRAY_SIZE(addresses_B_1),
3105 .ips = addresses_B_1,
3106 .apply_expected = True
3111 * sgroup,tombstone vs. sgroup,tombstone
3112 * => should NOT be replaced
3115 .line = __location__,
3116 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3119 .type = WREPL_TYPE_SGROUP,
3120 .state = WREPL_STATE_TOMBSTONE,
3121 .node = WREPL_NODE_B,
3123 .num_ips = ARRAY_SIZE(addresses_B_1),
3124 .ips = addresses_B_1,
3125 .apply_expected = True
3129 .type = WREPL_TYPE_SGROUP,
3130 .state = WREPL_STATE_TOMBSTONE,
3131 .node = WREPL_NODE_B,
3133 .num_ips = ARRAY_SIZE(addresses_A_1),
3134 .ips = addresses_A_1,
3135 .apply_expected = True
3140 * special groups vs multi homed section,
3143 * sgroup,active vs. mhomed,active
3144 * => should NOT be replaced
3147 .line = __location__,
3148 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3151 .type = WREPL_TYPE_SGROUP,
3152 .state = WREPL_STATE_ACTIVE,
3153 .node = WREPL_NODE_B,
3155 .num_ips = ARRAY_SIZE(addresses_A_1),
3156 .ips = addresses_A_1,
3157 .apply_expected = True
3161 .type = WREPL_TYPE_MHOMED,
3162 .state = WREPL_STATE_ACTIVE,
3163 .node = WREPL_NODE_B,
3165 .num_ips = ARRAY_SIZE(addresses_A_1),
3166 .ips = addresses_A_1,
3167 .apply_expected = False
3172 * sgroup,active vs. mhomed,tombstone
3173 * => should NOT be replaced
3176 .line = __location__,
3177 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3180 .type = WREPL_TYPE_SGROUP,
3181 .state = WREPL_STATE_ACTIVE,
3182 .node = WREPL_NODE_B,
3184 .num_ips = ARRAY_SIZE(addresses_A_1),
3185 .ips = addresses_A_1,
3186 .apply_expected = True
3190 .type = WREPL_TYPE_MHOMED,
3191 .state = WREPL_STATE_TOMBSTONE,
3192 .node = WREPL_NODE_B,
3194 .num_ips = ARRAY_SIZE(addresses_A_1),
3195 .ips = addresses_A_1,
3196 .apply_expected = False
3201 * sgroup,released vs. mhomed,active
3202 * => should be replaced
3205 .line = __location__,
3206 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3209 .type = WREPL_TYPE_SGROUP,
3210 .state = WREPL_STATE_RELEASED,
3211 .node = WREPL_NODE_B,
3213 .num_ips = ARRAY_SIZE(addresses_A_1),
3214 .ips = addresses_A_1,
3215 .apply_expected = False
3219 .type = WREPL_TYPE_MHOMED,
3220 .state = WREPL_STATE_ACTIVE,
3221 .node = WREPL_NODE_B,
3223 .num_ips = ARRAY_SIZE(addresses_B_1),
3224 .ips = addresses_B_1,
3225 .apply_expected = True
3230 * sgroup,released vs. mhomed,tombstone
3231 * => should be replaced
3234 .line = __location__,
3235 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3238 .type = WREPL_TYPE_SGROUP,
3239 .state = WREPL_STATE_RELEASED,
3240 .node = WREPL_NODE_B,
3242 .num_ips = ARRAY_SIZE(addresses_B_1),
3243 .ips = addresses_B_1,
3244 .apply_expected = False
3248 .type = WREPL_TYPE_MHOMED,
3249 .state = WREPL_STATE_TOMBSTONE,
3250 .node = WREPL_NODE_B,
3252 .num_ips = ARRAY_SIZE(addresses_A_1),
3253 .ips = addresses_A_1,
3254 .apply_expected = True
3259 * sgroup,tombstone vs. mhomed,active
3260 * => should be replaced
3263 .line = __location__,
3264 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3267 .type = WREPL_TYPE_SGROUP,
3268 .state = WREPL_STATE_TOMBSTONE,
3269 .node = WREPL_NODE_B,
3271 .num_ips = ARRAY_SIZE(addresses_A_1),