r11416: add some more comments
[samba.git] / source4 / torture / nbt / winsreplication.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    WINS replication testing
5
6    Copyright (C) Andrew Tridgell 2005
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "libcli/nbt/libnbt.h"
25 #include "libcli/wrepl/winsrepl.h"
26 #include "lib/events/events.h"
27 #include "lib/socket/socket.h"
28 #include "system/time.h"
29
30 #define CHECK_STATUS(status, correct) do { \
31         if (!NT_STATUS_EQUAL(status, correct)) { \
32                 printf("(%s) Incorrect status %s - should be %s\n", \
33                        __location__, nt_errstr(status), nt_errstr(correct)); \
34                 ret = False; \
35                 goto done; \
36         }} while (0)
37
38 #define CHECK_VALUE(v, correct) do { \
39         if ((v) != (correct)) { \
40                 printf("(%s) Incorrect value %s=%d - should be %d\n", \
41                        __location__, #v, v, correct); \
42                 ret = False; \
43                 goto done; \
44         }} while (0)
45
46 #define CHECK_VALUE_UINT64(v, correct) do { \
47         if ((v) != (correct)) { \
48                 printf("(%s) Incorrect value %s=%llu - should be %llu\n", \
49                        __location__, #v, v, correct); \
50                 ret = False; \
51                 goto done; \
52         }} while (0)
53
54 #define CHECK_VALUE_STRING(v, correct) do { \
55         if ( ((!v) && (correct)) || \
56              ((v) && (!correct)) || \
57              ((v) && (correct) && strcmp(v,correct) != 0)) { \
58                 printf("(%s) Incorrect value %s='%s' - should be '%s'\n", \
59                        __location__, #v, v, correct); \
60                 ret = False; \
61                 goto done; \
62         }} while (0)
63
64 #define _NBT_NAME(n,t,s) {\
65         .name   = n,\
66         .type   = t,\
67         .scope  = s\
68 }
69
70 static const char *wrepl_name_type_string(enum wrepl_name_type type)
71 {
72         switch (type) {
73         case WREPL_TYPE_UNIQUE: return "UNIQUE";
74         case WREPL_TYPE_GROUP: return "GROUP";
75         case WREPL_TYPE_SGROUP: return "SGROUP";
76         case WREPL_TYPE_MHOMED: return "MHOMED";
77         }
78         return "UNKNOWN_TYPE";
79 }
80
81 static const char *wrepl_name_state_string(enum wrepl_name_state state)
82 {
83         switch (state) {
84         case WREPL_STATE_ACTIVE: return "ACTIVE";
85         case WREPL_STATE_RELEASED: return "RELEASED";
86         case WREPL_STATE_TOMBSTONE: return "TOMBSTONE";
87         case WREPL_STATE_RESERVED: return "RESERVED";
88         }
89         return "UNKNOWN_STATE";
90 }
91
92 /*
93   test how assoc_ctx's are only usable on the connection
94   they are created on.
95 */
96 static BOOL test_assoc_ctx1(TALLOC_CTX *mem_ctx, const char *address)
97 {
98         BOOL ret = True;
99         struct wrepl_request *req;
100         struct wrepl_socket *wrepl_socket1;
101         struct wrepl_associate associate1;
102         struct wrepl_socket *wrepl_socket2;
103         struct wrepl_associate associate2;
104         struct wrepl_pull_table pull_table;
105         struct wrepl_packet *rep_packet;
106         struct wrepl_associate_stop assoc_stop;
107         NTSTATUS status;
108
109         if (!lp_parm_bool(-1, "torture", "dangerous", False)) {
110                 printf("winsrepl: cross connection assoc_ctx usage disabled - enable dangerous tests to use\n");
111                 return True;
112         }
113
114         printf("Test if assoc_ctx is only valid on the conection it was created on\n");
115
116         wrepl_socket1 = wrepl_socket_init(mem_ctx, NULL);
117         wrepl_socket2 = wrepl_socket_init(mem_ctx, NULL);
118
119         printf("Setup 2 wrepl connections\n");
120         status = wrepl_connect(wrepl_socket1, NULL, address);
121         CHECK_STATUS(status, NT_STATUS_OK);
122
123         status = wrepl_connect(wrepl_socket2, NULL, address);
124         CHECK_STATUS(status, NT_STATUS_OK);
125
126         printf("Send a start association request (conn1)\n");
127         status = wrepl_associate(wrepl_socket1, &associate1);
128         CHECK_STATUS(status, NT_STATUS_OK);
129
130         printf("association context (conn1): 0x%x\n", associate1.out.assoc_ctx);
131
132         printf("Send a start association request (conn2)\n");
133         status = wrepl_associate(wrepl_socket2, &associate2);
134         CHECK_STATUS(status, NT_STATUS_OK);
135
136         printf("association context (conn2): 0x%x\n", associate2.out.assoc_ctx);
137
138         printf("Send a replication table query, with assoc 1 (conn2), the anwser should be on conn1\n");
139         pull_table.in.assoc_ctx = associate1.out.assoc_ctx;
140         req = wrepl_pull_table_send(wrepl_socket2, &pull_table);
141         req->send_only = True;
142         status = wrepl_request_recv(req, mem_ctx, &rep_packet);
143         CHECK_STATUS(status, NT_STATUS_OK);
144
145         printf("Send a association request (conn2), to make sure the last request was ignored\n");
146         status = wrepl_associate(wrepl_socket2, &associate2);
147         CHECK_STATUS(status, NT_STATUS_OK);
148
149         printf("Send a replication table query, with invalid assoc (conn1), receive answer from conn2\n");
150         pull_table.in.assoc_ctx = 0;
151         req = wrepl_pull_table_send(wrepl_socket1, &pull_table);
152         status = wrepl_request_recv(req, mem_ctx, &rep_packet);
153         CHECK_STATUS(status, NT_STATUS_OK);
154
155         printf("Send a association request (conn1), to make sure the last request was handled correct\n");
156         status = wrepl_associate(wrepl_socket1, &associate2);
157         CHECK_STATUS(status, NT_STATUS_OK);
158
159         assoc_stop.in.assoc_ctx = associate1.out.assoc_ctx;
160         assoc_stop.in.reason    = 4;
161         printf("Send a association stop request (conn1), reson: %u\n", assoc_stop.in.reason);
162         status = wrepl_associate_stop(wrepl_socket1, &assoc_stop);
163         CHECK_STATUS(status, NT_STATUS_END_OF_FILE);
164
165         assoc_stop.in.assoc_ctx = associate2.out.assoc_ctx;
166         assoc_stop.in.reason    = 0;
167         printf("Send a association stop request (conn2), reson: %u\n", assoc_stop.in.reason);
168         status = wrepl_associate_stop(wrepl_socket2, &assoc_stop);
169         CHECK_STATUS(status, NT_STATUS_OK);
170
171 done:
172         printf("Close 2 wrepl connections\n");
173         talloc_free(wrepl_socket1);
174         talloc_free(wrepl_socket2);
175         return ret;
176 }
177
178 /*
179   test if we always get back the same assoc_ctx
180 */
181 static BOOL test_assoc_ctx2(TALLOC_CTX *mem_ctx, const char *address)
182 {
183         BOOL ret = True;
184         struct wrepl_socket *wrepl_socket;
185         struct wrepl_associate associate;
186         uint32_t assoc_ctx1;
187         NTSTATUS status;
188
189         printf("Test if we always get back the same assoc_ctx\n");
190
191         wrepl_socket = wrepl_socket_init(mem_ctx, NULL);
192         
193         printf("Setup wrepl connections\n");
194         status = wrepl_connect(wrepl_socket, NULL, address);
195         CHECK_STATUS(status, NT_STATUS_OK);
196
197
198         printf("Send 1st start association request\n");
199         status = wrepl_associate(wrepl_socket, &associate);
200         CHECK_STATUS(status, NT_STATUS_OK);
201         assoc_ctx1 = associate.out.assoc_ctx;
202         printf("1st association context: 0x%x\n", associate.out.assoc_ctx);
203
204         printf("Send 2nd start association request\n");
205         status = wrepl_associate(wrepl_socket, &associate);
206         CHECK_VALUE(associate.out.assoc_ctx, assoc_ctx1);
207         CHECK_STATUS(status, NT_STATUS_OK);
208         printf("2nd association context: 0x%x\n", associate.out.assoc_ctx);
209
210         printf("Send 3rd start association request\n");
211         status = wrepl_associate(wrepl_socket, &associate);
212         CHECK_VALUE(associate.out.assoc_ctx, assoc_ctx1);
213         CHECK_STATUS(status, NT_STATUS_OK);
214         printf("3rd association context: 0x%x\n", associate.out.assoc_ctx);
215
216 done:
217         printf("Close wrepl connections\n");
218         talloc_free(wrepl_socket);
219         return ret;
220 }
221
222
223 /*
224   display a replication entry
225 */
226 static void display_entry(TALLOC_CTX *mem_ctx, struct wrepl_name *name)
227 {
228         int i;
229
230         printf("%s\n", nbt_name_string(mem_ctx, &name->name));
231         printf("\tTYPE:%u STATE:%u NODE:%u STATIC:%u VERSION_ID: %llu\n",
232                 name->type, name->state, name->node, name->is_static, name->version_id);
233         printf("\tRAW_FLAGS: 0x%08X OWNER: %-15s\n",
234                 name->raw_flags, name->owner);
235         for (i=0;i<name->num_addresses;i++) {
236                 printf("\tADDR: %-15s OWNER: %-15s\n", 
237                         name->addresses[i].address, name->addresses[i].owner);
238         }
239 }
240
241 /*
242   test a full replication dump from a WINS server
243 */
244 static BOOL test_wins_replication(TALLOC_CTX *mem_ctx, const char *address)
245 {
246         BOOL ret = True;
247         struct wrepl_socket *wrepl_socket;
248         NTSTATUS status;
249         int i, j;
250         struct wrepl_associate associate;
251         struct wrepl_pull_table pull_table;
252         struct wrepl_pull_names pull_names;
253
254         printf("Test one pull replication cycle\n");
255
256         wrepl_socket = wrepl_socket_init(mem_ctx, NULL);
257         
258         printf("Setup wrepl connections\n");
259         status = wrepl_connect(wrepl_socket, NULL, address);
260         CHECK_STATUS(status, NT_STATUS_OK);
261
262         printf("Send a start association request\n");
263
264         status = wrepl_associate(wrepl_socket, &associate);
265         CHECK_STATUS(status, NT_STATUS_OK);
266
267         printf("association context: 0x%x\n", associate.out.assoc_ctx);
268
269         printf("Send a replication table query\n");
270         pull_table.in.assoc_ctx = associate.out.assoc_ctx;
271
272         status = wrepl_pull_table(wrepl_socket, mem_ctx, &pull_table);
273         if (NT_STATUS_EQUAL(NT_STATUS_NETWORK_ACCESS_DENIED,status)) {
274                 struct wrepl_packet packet;
275                 struct wrepl_request *req;
276
277                 ZERO_STRUCT(packet);
278                 packet.opcode                      = WREPL_OPCODE_BITS;
279                 packet.assoc_ctx                   = associate.out.assoc_ctx;
280                 packet.mess_type                   = WREPL_STOP_ASSOCIATION;
281                 packet.message.stop.reason         = 0;
282
283                 req = wrepl_request_send(wrepl_socket, &packet);
284                 talloc_free(req);
285
286                 printf("failed - We are not a valid pull partner for the server\n");
287                 ret = False;
288                 goto done;
289         }
290         CHECK_STATUS(status, NT_STATUS_OK);
291
292         printf("Found %d replication partners\n", pull_table.out.num_partners);
293
294         for (i=0;i<pull_table.out.num_partners;i++) {
295                 struct wrepl_wins_owner *partner = &pull_table.out.partners[i];
296                 printf("%s   max_version=%6llu   min_version=%6llu type=%d\n",
297                        partner->address, 
298                        partner->max_version, 
299                        partner->min_version, 
300                        partner->type);
301
302                 pull_names.in.assoc_ctx = associate.out.assoc_ctx;
303                 pull_names.in.partner = *partner;
304                 
305                 status = wrepl_pull_names(wrepl_socket, mem_ctx, &pull_names);
306                 CHECK_STATUS(status, NT_STATUS_OK);
307
308                 printf("Received %d names\n", pull_names.out.num_names);
309
310                 for (j=0;j<pull_names.out.num_names;j++) {
311                         display_entry(mem_ctx, &pull_names.out.names[j]);
312                 }
313         }
314
315 done:
316         printf("Close wrepl connections\n");
317         talloc_free(wrepl_socket);
318         return ret;
319 }
320
321 struct test_wrepl_conflict_conn {
322         const char *address;
323         struct wrepl_socket *pull;
324         uint32_t pull_assoc;
325
326 #define TEST_OWNER_A_ADDRESS "127.65.65.1"
327 #define TEST_ADDRESS_A_PREFIX "127.0.65"
328 #define TEST_OWNER_B_ADDRESS "127.66.66.1"
329 #define TEST_ADDRESS_B_PREFIX "127.0.66"
330
331         struct wrepl_wins_owner a, b, c;
332
333         const char *myaddr;
334         struct nbt_name_socket *nbtsock;
335
336         struct nbt_name_socket *nbtsock_srv;
337
338         uint32_t addresses_1_num;
339         struct wrepl_ip *addresses_1;
340 };
341
342 static const struct wrepl_ip addresses_A_1[] = {
343         {
344         .owner  = TEST_OWNER_A_ADDRESS,
345         .ip     = TEST_ADDRESS_A_PREFIX".1"
346         }
347 };
348 static const struct wrepl_ip addresses_A_2[] = {
349         {
350         .owner  = TEST_OWNER_A_ADDRESS,
351         .ip     = TEST_ADDRESS_A_PREFIX".2"
352         }
353 };
354 static const struct wrepl_ip addresses_A_3_4[] = {
355         {
356         .owner  = TEST_OWNER_A_ADDRESS,
357         .ip     = TEST_ADDRESS_A_PREFIX".3"
358         },
359         {
360         .owner  = TEST_OWNER_A_ADDRESS,
361         .ip     = TEST_ADDRESS_A_PREFIX".4"
362         }
363 };
364
365 static const struct wrepl_ip addresses_B_1[] = {
366         {
367         .owner  = TEST_OWNER_B_ADDRESS,
368         .ip     = TEST_ADDRESS_B_PREFIX".1"
369         }
370 };
371 static const struct wrepl_ip addresses_B_2[] = {
372         {
373         .owner  = TEST_OWNER_B_ADDRESS,
374         .ip     = TEST_ADDRESS_B_PREFIX".2"
375         }
376 };
377 static const struct wrepl_ip addresses_B_3_4[] = {
378         {
379         .owner  = TEST_OWNER_B_ADDRESS,
380         .ip     = TEST_ADDRESS_B_PREFIX".3"
381         },
382         {
383         .owner  = TEST_OWNER_B_ADDRESS,
384         .ip     = TEST_ADDRESS_B_PREFIX".4"
385         }
386 };
387
388 static struct test_wrepl_conflict_conn *test_create_conflict_ctx(TALLOC_CTX *mem_ctx,
389                                                                  const char *address)
390 {
391         struct test_wrepl_conflict_conn *ctx;
392         struct wrepl_associate associate;
393         struct wrepl_pull_table pull_table;
394         NTSTATUS status;
395         uint32_t i;
396
397         ctx = talloc_zero(mem_ctx, struct test_wrepl_conflict_conn);
398         if (!ctx) return NULL;
399
400         ctx->address    = address;
401         ctx->pull       = wrepl_socket_init(ctx, NULL);
402         if (!ctx->pull) return NULL;
403
404         printf("Setup wrepl conflict pull connection\n");
405         status = wrepl_connect(ctx->pull, NULL, ctx->address);
406         if (!NT_STATUS_IS_OK(status)) return NULL;
407
408         status = wrepl_associate(ctx->pull, &associate);
409         if (!NT_STATUS_IS_OK(status)) return NULL;
410
411         ctx->pull_assoc = associate.out.assoc_ctx;
412
413         ctx->a.address          = TEST_OWNER_A_ADDRESS;
414         ctx->a.max_version      = 0;
415         ctx->a.min_version      = 0;
416         ctx->a.type             = 1;
417
418         ctx->b.address          = TEST_OWNER_B_ADDRESS;
419         ctx->b.max_version      = 0;
420         ctx->b.min_version      = 0;
421         ctx->b.type             = 1;
422
423         ctx->c.address          = address;
424         ctx->c.max_version      = 0;
425         ctx->c.min_version      = 0;
426         ctx->c.type             = 1;
427
428         pull_table.in.assoc_ctx = ctx->pull_assoc;
429         status = wrepl_pull_table(ctx->pull, ctx->pull, &pull_table);
430         if (!NT_STATUS_IS_OK(status)) return NULL;
431
432         for (i=0; i < pull_table.out.num_partners; i++) {
433                 if (strcmp(TEST_OWNER_A_ADDRESS,pull_table.out.partners[i].address)==0) {
434                         ctx->a.max_version      = pull_table.out.partners[i].max_version;
435                         ctx->a.min_version      = pull_table.out.partners[i].min_version;
436                 }
437                 if (strcmp(TEST_OWNER_B_ADDRESS,pull_table.out.partners[i].address)==0) {
438                         ctx->b.max_version      = pull_table.out.partners[i].max_version;
439                         ctx->b.min_version      = pull_table.out.partners[i].min_version;
440                 }
441                 if (strcmp(address,pull_table.out.partners[i].address)==0) {
442                         ctx->c.max_version      = pull_table.out.partners[i].max_version;
443                         ctx->c.min_version      = pull_table.out.partners[i].min_version;
444                 }
445         }
446
447         talloc_free(pull_table.out.partners);
448
449         ctx->myaddr = talloc_strdup(mem_ctx, iface_best_ip(address));
450         if (!ctx->myaddr) return NULL;
451
452         ctx->nbtsock = nbt_name_socket_init(ctx, NULL);
453         if (!ctx->nbtsock) return NULL;
454
455         status = socket_listen(ctx->nbtsock->sock, ctx->myaddr, 0, 0, 0);
456         if (!NT_STATUS_IS_OK(status)) return NULL;
457
458         ctx->nbtsock_srv = nbt_name_socket_init(ctx, NULL);
459         if (!ctx->nbtsock_srv) return NULL;
460
461         status = socket_listen(ctx->nbtsock_srv->sock, ctx->myaddr, lp_nbt_port(), 0, 0);
462         if (!NT_STATUS_IS_OK(status)) {
463                 talloc_free(ctx->nbtsock_srv);
464                 ctx->nbtsock_srv = NULL;
465         }
466
467         ctx->addresses_1_num = 1;
468         ctx->addresses_1 = talloc_array(ctx, struct wrepl_ip, ctx->addresses_1_num);
469         if (!ctx->addresses_1) return NULL;
470         ctx->addresses_1[0].owner       = ctx->c.address;
471         ctx->addresses_1[0].ip          = ctx->myaddr;
472
473         return ctx;
474 }
475
476 static BOOL test_wrepl_update_one(struct test_wrepl_conflict_conn *ctx,
477                                   const struct wrepl_wins_owner *owner,
478                                   const struct wrepl_wins_name *name)
479 {
480         BOOL ret = True;
481         struct wrepl_socket *wrepl_socket;
482         struct wrepl_associate associate;
483         struct wrepl_packet update_packet, repl_send;
484         struct wrepl_table *update;
485         struct wrepl_wins_owner wrepl_wins_owners[1];
486         struct wrepl_packet *repl_recv;
487         struct wrepl_wins_owner *send_request;
488         struct wrepl_send_reply *send_reply;
489         struct wrepl_wins_name wrepl_wins_names[1];
490         uint32_t assoc_ctx;
491         NTSTATUS status;
492
493         wrepl_socket = wrepl_socket_init(ctx, NULL);
494
495         status = wrepl_connect(wrepl_socket, NULL, ctx->address);
496         CHECK_STATUS(status, NT_STATUS_OK);
497
498         status = wrepl_associate(wrepl_socket, &associate);
499         CHECK_STATUS(status, NT_STATUS_OK);
500         assoc_ctx = associate.out.assoc_ctx;
501
502         /* now send a WREPL_REPL_UPDATE message */
503         ZERO_STRUCT(update_packet);
504         update_packet.opcode                    = WREPL_OPCODE_BITS;
505         update_packet.assoc_ctx                 = assoc_ctx;
506         update_packet.mess_type                 = WREPL_REPLICATION;
507         update_packet.message.replication.command       = WREPL_REPL_UPDATE;
508         update  = &update_packet.message.replication.info.table;
509
510         update->partner_count   = ARRAY_SIZE(wrepl_wins_owners);
511         update->partners        = wrepl_wins_owners;
512         update->initiator       = "0.0.0.0";
513
514         wrepl_wins_owners[0]    = *owner;
515
516         status = wrepl_request(wrepl_socket, wrepl_socket,
517                                &update_packet, &repl_recv);
518         CHECK_STATUS(status, NT_STATUS_OK);
519         CHECK_VALUE(repl_recv->mess_type, WREPL_REPLICATION);
520         CHECK_VALUE(repl_recv->message.replication.command, WREPL_REPL_SEND_REQUEST);
521         send_request = &repl_recv->message.replication.info.owner;
522
523         ZERO_STRUCT(repl_send);
524         repl_send.opcode                        = WREPL_OPCODE_BITS;
525         repl_send.assoc_ctx                     = assoc_ctx;
526         repl_send.mess_type                     = WREPL_REPLICATION;
527         repl_send.message.replication.command   = WREPL_REPL_SEND_REPLY;
528         send_reply = &repl_send.message.replication.info.reply;
529
530         send_reply->num_names   = ARRAY_SIZE(wrepl_wins_names);
531         send_reply->names       = wrepl_wins_names;
532
533         wrepl_wins_names[0]     = *name;
534
535         status = wrepl_request(wrepl_socket, wrepl_socket,
536                                &repl_send, &repl_recv);
537         CHECK_STATUS(status, NT_STATUS_OK);
538         CHECK_VALUE(repl_recv->mess_type, WREPL_STOP_ASSOCIATION);
539         CHECK_VALUE(repl_recv->message.stop.reason, 0);
540
541 done:
542         talloc_free(wrepl_socket);
543         return ret;
544 }
545
546 #if 0
547 static BOOL test_wrepl_update_two(struct test_wrepl_conflict_conn *ctx,
548                                   const struct wrepl_wins_owner *owner,
549                                   const struct wrepl_wins_name *name1,
550                                   const struct wrepl_wins_name *name2)
551 {
552         BOOL ret = True;
553         struct wrepl_socket *wrepl_socket;
554         struct wrepl_associate associate;
555         struct wrepl_packet update_packet, repl_send;
556         struct wrepl_table *update;
557         struct wrepl_wins_owner wrepl_wins_owners[1];
558         struct wrepl_packet *repl_recv;
559         struct wrepl_wins_owner *send_request;
560         struct wrepl_send_reply *send_reply;
561         struct wrepl_wins_name wrepl_wins_names[2];
562         uint32_t assoc_ctx;
563         NTSTATUS status;
564
565         wrepl_socket = wrepl_socket_init(ctx, NULL);
566
567         status = wrepl_connect(wrepl_socket, NULL, ctx->address);
568         CHECK_STATUS(status, NT_STATUS_OK);
569
570         status = wrepl_associate(wrepl_socket, &associate);
571         CHECK_STATUS(status, NT_STATUS_OK);
572         assoc_ctx = associate.out.assoc_ctx;
573
574         /* now send a WREPL_REPL_UPDATE message */
575         ZERO_STRUCT(update_packet);
576         update_packet.opcode                    = WREPL_OPCODE_BITS;
577         update_packet.assoc_ctx                 = assoc_ctx;
578         update_packet.mess_type                 = WREPL_REPLICATION;
579         update_packet.message.replication.command       = WREPL_REPL_UPDATE;
580         update  = &update_packet.message.replication.info.table;
581
582         update->partner_count   = ARRAY_SIZE(wrepl_wins_owners);
583         update->partners        = wrepl_wins_owners;
584         update->initiator       = "0.0.0.0";
585
586         wrepl_wins_owners[0]    = *owner;
587
588         status = wrepl_request(wrepl_socket, wrepl_socket,
589                                &update_packet, &repl_recv);
590         CHECK_STATUS(status, NT_STATUS_OK);
591         CHECK_VALUE(repl_recv->mess_type, WREPL_REPLICATION);
592         CHECK_VALUE(repl_recv->message.replication.command, WREPL_REPL_SEND_REQUEST);
593         send_request = &repl_recv->message.replication.info.owner;
594
595         ZERO_STRUCT(repl_send);
596         repl_send.opcode                        = WREPL_OPCODE_BITS;
597         repl_send.assoc_ctx                     = assoc_ctx;
598         repl_send.mess_type                     = WREPL_REPLICATION;
599         repl_send.message.replication.command   = WREPL_REPL_SEND_REPLY;
600         send_reply = &repl_send.message.replication.info.reply;
601
602         send_reply->num_names   = ARRAY_SIZE(wrepl_wins_names);
603         send_reply->names       = wrepl_wins_names;
604
605         wrepl_wins_names[0]     = *name1;
606         wrepl_wins_names[1]     = *name2;
607
608         status = wrepl_request(wrepl_socket, wrepl_socket,
609                                &repl_send, &repl_recv);
610         CHECK_STATUS(status, NT_STATUS_OK);
611         CHECK_VALUE(repl_recv->mess_type, WREPL_STOP_ASSOCIATION);
612         CHECK_VALUE(repl_recv->message.stop.reason, 0);
613
614 done:
615         talloc_free(wrepl_socket);
616         return ret;
617 }
618 #endif
619
620 static BOOL test_wrepl_is_applied(struct test_wrepl_conflict_conn *ctx,
621                                   const struct wrepl_wins_owner *owner,
622                                   const struct wrepl_wins_name *name,
623                                   BOOL expected)
624 {
625         BOOL ret = True;
626         NTSTATUS status;
627         struct wrepl_pull_names pull_names;
628         struct wrepl_name *names;
629
630         pull_names.in.assoc_ctx = ctx->pull_assoc;
631         pull_names.in.partner   = *owner;
632         pull_names.in.partner.min_version = pull_names.in.partner.max_version;
633                 
634         status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
635         CHECK_STATUS(status, NT_STATUS_OK);
636         CHECK_VALUE(pull_names.out.num_names, (expected?1:0));
637
638         names = pull_names.out.names;
639
640         if (expected) {
641                 uint32_t flags = WREPL_NAME_FLAGS(names[0].type,
642                                                   names[0].state,
643                                                   names[0].node,
644                                                   names[0].is_static);
645                 CHECK_VALUE(names[0].name.type, name->name->type);
646                 CHECK_VALUE_STRING(names[0].name.name, name->name->name);
647                 CHECK_VALUE_STRING(names[0].name.scope, name->name->scope);
648                 CHECK_VALUE(flags, name->flags);
649                 CHECK_VALUE_UINT64(names[0].version_id, name->id);
650
651                 if (flags & 2) {
652                         CHECK_VALUE(names[0].num_addresses,
653                                     name->addresses.addresses.num_ips);
654                 } else {
655                         CHECK_VALUE(names[0].num_addresses, 1);
656                         CHECK_VALUE_STRING(names[0].addresses[0].address,
657                                            name->addresses.ip);
658                 }
659         }
660 done:
661         talloc_free(pull_names.out.names);
662         return ret;
663 }
664
665 static BOOL test_wrepl_is_merged(struct test_wrepl_conflict_conn *ctx,
666                                  const struct wrepl_wins_name *name1,
667                                  const struct wrepl_wins_name *name2)
668 {
669         return True;
670 #if 0
671         BOOL ret = True;
672         NTSTATUS status;
673         struct wrepl_pull_names pull_names;
674         struct wrepl_name *names;
675         uint32_t num_ips;
676
677         pull_names.in.assoc_ctx = ctx->pull_assoc;
678         pull_names.in.partner   = ctx->c;
679         pull_names.in.partner.min_version = ctx->c.max_version-1;
680
681         status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
682         CHECK_STATUS(status, NT_STATUS_OK);
683         CHECK_VALUE(pull_names.out.num_names, 1);
684
685         names = pull_names.out.names;
686
687         num_ips = name1->addresses.addresses.num_ips + name2->addresses.addresses.num_ips;
688
689         CHECK_VALUE(names[0].name.type, name1->name->type);
690         CHECK_VALUE_STRING(names[0].name.name, name1->name->name);
691         CHECK_VALUE_STRING(names[0].name.scope, name1->name->scope);
692         CHECK_VALUE(names[0].type, WREPL_TYPE_SGROUP);
693         CHECK_VALUE(names[0].state, (num_ips>0?WREPL_STATE_ACTIVE:WREPL_STATE_RELEASED));
694         CHECK_VALUE_UINT64(names[0].version_id, ctx->c.max_version);
695
696         CHECK_VALUE(names[0].num_addresses,
697                     name1->addresses.addresses.num_ips+
698                     name2->addresses.addresses.num_ips);
699 done:
700         talloc_free(pull_names.out.names);
701         return ret;
702 #endif
703 }
704
705 static BOOL test_conflict_same_owner(struct test_wrepl_conflict_conn *ctx)
706 {
707         BOOL ret = True;
708         struct nbt_name name;
709         struct wrepl_wins_name wins_name1;
710         struct wrepl_wins_name wins_name2;
711         struct wrepl_wins_name *wins_name_tmp;
712         struct wrepl_wins_name *wins_name_last;
713         struct wrepl_wins_name *wins_name_cur;
714         uint32_t i,j;
715         uint8_t types[] = { 0x00, 0x1C };
716         struct {
717                 enum wrepl_name_type type;
718                 enum wrepl_name_state state;
719                 enum wrepl_name_node node;
720                 BOOL is_static;
721                 uint32_t num_ips;
722                 const struct wrepl_ip *ips;
723         } records[] = {
724                 {
725                 .type           = WREPL_TYPE_GROUP,
726                 .state          = WREPL_STATE_ACTIVE,
727                 .node           = WREPL_NODE_B,
728                 .is_static      = False,
729                 .num_ips        = ARRAY_SIZE(addresses_A_1),
730                 .ips            = addresses_A_1,
731                 },{
732                 .type           = WREPL_TYPE_UNIQUE,
733                 .state          = WREPL_STATE_ACTIVE,
734                 .node           = WREPL_NODE_B,
735                 .is_static      = False,
736                 .num_ips        = ARRAY_SIZE(addresses_A_1),
737                 .ips            = addresses_A_1,
738                 },{
739                 .type           = WREPL_TYPE_UNIQUE,
740                 .state          = WREPL_STATE_ACTIVE,
741                 .node           = WREPL_NODE_B,
742                 .is_static      = False,
743                 .num_ips        = ARRAY_SIZE(addresses_A_2),
744                 .ips            = addresses_A_2,
745                 },{
746                 .type           = WREPL_TYPE_UNIQUE,
747                 .state          = WREPL_STATE_ACTIVE,
748                 .node           = WREPL_NODE_B,
749                 .is_static      = True,
750                 .num_ips        = ARRAY_SIZE(addresses_A_1),
751                 .ips            = addresses_A_1,
752                 },{
753                 .type           = WREPL_TYPE_UNIQUE,
754                 .state          = WREPL_STATE_ACTIVE,
755                 .node           = WREPL_NODE_B,
756                 .is_static      = False,
757                 .num_ips        = ARRAY_SIZE(addresses_A_2),
758                 .ips            = addresses_A_2,
759                 },{
760                 .type           = WREPL_TYPE_SGROUP,
761                 .state          = WREPL_STATE_TOMBSTONE,
762                 .node           = WREPL_NODE_B,
763                 .is_static      = False,
764                 .num_ips        = ARRAY_SIZE(addresses_A_2),
765                 .ips            = addresses_A_2,
766                 },{
767                 .type           = WREPL_TYPE_MHOMED,
768                 .state          = WREPL_STATE_TOMBSTONE,
769                 .node           = WREPL_NODE_B,
770                 .is_static      = False,
771                 .num_ips        = ARRAY_SIZE(addresses_A_1),
772                 .ips            = addresses_A_1,
773                 },{
774                 .type           = WREPL_TYPE_MHOMED,
775                 .state          = WREPL_STATE_RELEASED,
776                 .node           = WREPL_NODE_B,
777                 .is_static      = False,
778                 .num_ips        = ARRAY_SIZE(addresses_A_2),
779                 .ips            = addresses_A_2,
780                 },{
781                 .type           = WREPL_TYPE_SGROUP,
782                 .state          = WREPL_STATE_ACTIVE,
783                 .node           = WREPL_NODE_B,
784                 .is_static      = False,
785                 .num_ips        = ARRAY_SIZE(addresses_A_1),
786                 .ips            = addresses_A_1,
787                 },{
788                 .type           = WREPL_TYPE_SGROUP,
789                 .state          = WREPL_STATE_ACTIVE,
790                 .node           = WREPL_NODE_B,
791                 .is_static      = False,
792                 .num_ips        = ARRAY_SIZE(addresses_A_3_4),
793                 .ips            = addresses_A_3_4,
794                 },{
795                 .type           = WREPL_TYPE_SGROUP,
796                 .state          = WREPL_STATE_TOMBSTONE,
797                 .node           = WREPL_NODE_B,
798                 .is_static      = False,
799                 .num_ips        = ARRAY_SIZE(addresses_B_3_4),
800                 .ips            = addresses_B_3_4,
801                 },{
802                 /* the last one should always be a unique,tomstone record! */
803                 .type           = WREPL_TYPE_UNIQUE,
804                 .state          = WREPL_STATE_TOMBSTONE,
805                 .node           = WREPL_NODE_B,
806                 .is_static      = False,
807                 .num_ips        = ARRAY_SIZE(addresses_A_1),
808                 .ips            = addresses_A_1,
809                 }
810         };
811
812         if (!ctx) return False;
813
814         name.name       = "_SAME_OWNER_A";
815         name.type       = 0;
816         name.scope      = NULL;
817
818         wins_name_tmp   = NULL;
819         wins_name_last  = &wins_name2;
820         wins_name_cur   = &wins_name1;
821
822         for (j=0; ret && j < ARRAY_SIZE(types); j++) {
823                 name.type = types[j];
824                 printf("Test Replica Conflicts with same owner[%s] for %s\n",
825                         nbt_name_string(ctx, &name), ctx->a.address);
826
827                 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
828                         wins_name_tmp   = wins_name_last;
829                         wins_name_last  = wins_name_cur;
830                         wins_name_cur   = wins_name_tmp;
831
832                         if (i > 0) {
833                                 printf("%s,%s%s vs. %s,%s%s with %s ip(s) => %s\n",
834                                         wrepl_name_type_string(records[i-1].type),
835                                         wrepl_name_state_string(records[i-1].state),
836                                         (records[i-1].is_static?",static":""),
837                                         wrepl_name_type_string(records[i].type),
838                                         wrepl_name_state_string(records[i].state),
839                                         (records[i].is_static?",static":""),
840                                         (records[i-1].ips==records[i].ips?"same":"different"),
841                                         "REPLACE");
842                         }
843
844                         wins_name_cur->name     = &name;
845                         wins_name_cur->flags    = WREPL_NAME_FLAGS(records[i].type,
846                                                                    records[i].state,
847                                                                    records[i].node,
848                                                                    records[i].is_static);
849                         wins_name_cur->id       = ++ctx->a.max_version;
850                         if (wins_name_cur->flags & 2) {
851                                 wins_name_cur->addresses.addresses.num_ips = records[i].num_ips;
852                                 wins_name_cur->addresses.addresses.ips     = discard_const(records[i].ips);
853                         } else {
854                                 wins_name_cur->addresses.ip = records[i].ips[0].ip;
855                         }
856                         wins_name_cur->unknown  = "255.255.255.255";
857
858                         ret &= test_wrepl_update_one(ctx, &ctx->a,wins_name_cur);
859                         if (records[i].state == WREPL_STATE_RELEASED) {
860                                 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_last, False);
861                                 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_cur, False);
862                         } else {
863                                 ret &= test_wrepl_is_applied(ctx, &ctx->a, wins_name_cur, True);
864                         }
865
866                         /* the first one is a cleanup run */
867                         if (!ret && i == 0) ret = True;
868
869                         if (!ret) {
870                                 printf("conflict handled wrong or record[%u]: %s\n", i, __location__);
871                                 return ret;
872                         }
873                 }
874         }
875         return ret;
876 }
877
878 static BOOL test_conflict_different_owner(struct test_wrepl_conflict_conn *ctx)
879 {
880         BOOL ret = True;
881         struct wrepl_wins_name wins_name1;
882         struct wrepl_wins_name wins_name2;
883         struct wrepl_wins_name *wins_name_r1;
884         struct wrepl_wins_name *wins_name_r2;
885         uint32_t i;
886         struct {
887                 const char *line; /* just better debugging */
888                 struct nbt_name name;
889                 BOOL extra; /* not the worst case, this is an extra test */
890                 BOOL cleanup;
891                 struct {
892                         struct wrepl_wins_owner *owner;
893                         enum wrepl_name_type type;
894                         enum wrepl_name_state state;
895                         enum wrepl_name_node node;
896                         BOOL is_static;
897                         uint32_t num_ips;
898                         const struct wrepl_ip *ips;
899                         BOOL apply_expected;
900                         BOOL merge_expected;
901                 } r1, r2;
902         } records[] = {
903         /* 
904          * NOTE: the first record and the last applied one
905          *       needs to be from the same owner,
906          *       to not conflict in the next smbtorture run!!!
907          */
908         {
909                 .line   = __location__,
910                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
911                 .cleanup= True,
912                 .r1     = {
913                         .owner          = &ctx->b,
914                         .type           = WREPL_TYPE_UNIQUE,
915                         .state          = WREPL_STATE_TOMBSTONE,
916                         .node           = WREPL_NODE_B,
917                         .is_static      = False,
918                         .num_ips        = ARRAY_SIZE(addresses_B_1),
919                         .ips            = addresses_B_1,
920                         .apply_expected = True /* ignored */
921                 },
922                 .r2     = {
923                         .owner          = &ctx->a,
924                         .type           = WREPL_TYPE_UNIQUE,
925                         .state          = WREPL_STATE_TOMBSTONE,
926                         .node           = WREPL_NODE_B,
927                         .is_static      = False,
928                         .num_ips        = ARRAY_SIZE(addresses_A_1),
929                         .ips            = addresses_A_1,
930                         .apply_expected = True /* ignored */
931                 }
932         },
933
934 /*
935  * unique vs unique section
936  */
937         /* 
938          * unique,active vs. unique,active
939          * => should be replaced
940          */
941         {
942                 .line   = __location__,
943                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
944                 .r1     = {
945                         .owner          = &ctx->a,
946                         .type           = WREPL_TYPE_UNIQUE,
947                         .state          = WREPL_STATE_ACTIVE,
948                         .node           = WREPL_NODE_B,
949                         .is_static      = False,
950                         .num_ips        = ARRAY_SIZE(addresses_A_1),
951                         .ips            = addresses_A_1,
952                         .apply_expected = True
953                 },
954                 .r2     = {
955                         .owner          = &ctx->b,
956                         .type           = WREPL_TYPE_UNIQUE,
957                         .state          = WREPL_STATE_ACTIVE,
958                         .node           = WREPL_NODE_B,
959                         .is_static      = False,
960                         .num_ips        = ARRAY_SIZE(addresses_B_1),
961                         .ips            = addresses_B_1,
962                         .apply_expected = True
963                 }
964         },
965
966         /* 
967          * unique,active vs. unique,tombstone
968          * => should NOT be replaced
969          */
970         {
971                 .line   = __location__,
972                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
973                 .r1     = {
974                         .owner          = &ctx->b,
975                         .type           = WREPL_TYPE_UNIQUE,
976                         .state          = WREPL_STATE_ACTIVE,
977                         .node           = WREPL_NODE_B,
978                         .is_static      = False,
979                         .num_ips        = ARRAY_SIZE(addresses_B_1),
980                         .ips            = addresses_B_1,
981                         .apply_expected = True
982                 },
983                 .r2     = {
984                         .owner          = &ctx->a,
985                         .type           = WREPL_TYPE_UNIQUE,
986                         .state          = WREPL_STATE_TOMBSTONE,
987                         .node           = WREPL_NODE_B,
988                         .is_static      = False,
989                         .num_ips        = ARRAY_SIZE(addresses_B_1),
990                         .ips            = addresses_B_1,
991                         .apply_expected = False
992                 }
993         },
994
995         /* 
996          * unique,released vs. unique,active
997          * => should be replaced
998          */
999         {
1000                 .line   = __location__,
1001                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1002                 .r1     = {
1003                         .owner          = &ctx->b,
1004                         .type           = WREPL_TYPE_UNIQUE,
1005                         .state          = WREPL_STATE_RELEASED,
1006                         .node           = WREPL_NODE_B,
1007                         .is_static      = False,
1008                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1009                         .ips            = addresses_B_1,
1010                         .apply_expected = False
1011                 },
1012                 .r2     = {
1013                         .owner          = &ctx->a,
1014                         .type           = WREPL_TYPE_UNIQUE,
1015                         .state          = WREPL_STATE_ACTIVE,
1016                         .node           = WREPL_NODE_B,
1017                         .is_static      = False,
1018                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1019                         .ips            = addresses_A_1,
1020                         .apply_expected = True
1021                 }
1022         },
1023
1024         /* 
1025          * unique,released vs. unique,tombstone
1026          * => should be replaced
1027          */
1028         {
1029                 .line   = __location__,
1030                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1031                 .r1     = {
1032                         .owner          = &ctx->a,
1033                         .type           = WREPL_TYPE_UNIQUE,
1034                         .state          = WREPL_STATE_RELEASED,
1035                         .node           = WREPL_NODE_B,
1036                         .is_static      = False,
1037                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1038                         .ips            = addresses_A_1,
1039                         .apply_expected = False
1040                 },
1041                 .r2     = {
1042                         .owner          = &ctx->b,
1043                         .type           = WREPL_TYPE_UNIQUE,
1044                         .state          = WREPL_STATE_TOMBSTONE,
1045                         .node           = WREPL_NODE_B,
1046                         .is_static      = False,
1047                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1048                         .ips            = addresses_B_1,
1049                         .apply_expected = True
1050                 }
1051         },
1052
1053         /* 
1054          * unique,tombstone vs. unique,active
1055          * => should be replaced
1056          */
1057         {
1058                 .line   = __location__,
1059                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1060                 .r1     = {
1061                         .owner          = &ctx->b,
1062                         .type           = WREPL_TYPE_UNIQUE,
1063                         .state          = WREPL_STATE_TOMBSTONE,
1064                         .node           = WREPL_NODE_B,
1065                         .is_static      = False,
1066                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1067                         .ips            = addresses_B_1,
1068                         .apply_expected = True
1069                 },
1070                 .r2     = {
1071                         .owner          = &ctx->a,
1072                         .type           = WREPL_TYPE_UNIQUE,
1073                         .state          = WREPL_STATE_ACTIVE,
1074                         .node           = WREPL_NODE_B,
1075                         .is_static      = False,
1076                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1077                         .ips            = addresses_A_1,
1078                         .apply_expected = True
1079                 }
1080         },
1081
1082         /* 
1083          * unique,tombstone vs. unique,tombstone
1084          * => should be replaced
1085          */
1086         {
1087                 .line   = __location__,
1088                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1089                 .r1     = {
1090                         .owner          = &ctx->a,
1091                         .type           = WREPL_TYPE_UNIQUE,
1092                         .state          = WREPL_STATE_TOMBSTONE,
1093                         .node           = WREPL_NODE_B,
1094                         .is_static      = False,
1095                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1096                         .ips            = addresses_A_1,
1097                         .apply_expected = True
1098                 },
1099                 .r2     = {
1100                         .owner          = &ctx->b,
1101                         .type           = WREPL_TYPE_UNIQUE,
1102                         .state          = WREPL_STATE_TOMBSTONE,
1103                         .node           = WREPL_NODE_B,
1104                         .is_static      = False,
1105                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1106                         .ips            = addresses_B_1,
1107                         .apply_expected = True
1108                 }
1109         },
1110
1111
1112 /*
1113  * unique vs normal groups section,
1114  */
1115         /* 
1116          * unique,active vs. group,active
1117          * => should be replaced
1118          */
1119         {
1120                 .line   = __location__,
1121                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1122                 .r1     = {
1123                         .owner          = &ctx->b,
1124                         .type           = WREPL_TYPE_UNIQUE,
1125                         .state          = WREPL_STATE_ACTIVE,
1126                         .node           = WREPL_NODE_B,
1127                         .is_static      = False,
1128                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1129                         .ips            = addresses_B_1,
1130                         .apply_expected = True
1131                 },
1132                 .r2     = {
1133                         .owner          = &ctx->a,
1134                         .type           = WREPL_TYPE_GROUP,
1135                         .state          = WREPL_STATE_ACTIVE,
1136                         .node           = WREPL_NODE_B,
1137                         .is_static      = False,
1138                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1139                         .ips            = addresses_A_1,
1140                         .apply_expected = True
1141                 }
1142         },
1143
1144         /* 
1145          * unique,active vs. group,tombstone
1146          * => should NOT be replaced
1147          */
1148         {
1149                 .line   = __location__,
1150                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1151                 .r1     = {
1152                         .owner          = &ctx->a,
1153                         .type           = WREPL_TYPE_UNIQUE,
1154                         .state          = WREPL_STATE_ACTIVE,
1155                         .node           = WREPL_NODE_B,
1156                         .is_static      = False,
1157                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1158                         .ips            = addresses_A_1,
1159                         .apply_expected = True
1160                 },
1161                 .r2     = {
1162                         .owner          = &ctx->b,
1163                         .type           = WREPL_TYPE_GROUP,
1164                         .state          = WREPL_STATE_TOMBSTONE,
1165                         .node           = WREPL_NODE_B,
1166                         .is_static      = False,
1167                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1168                         .ips            = addresses_A_1,
1169                         .apply_expected = False
1170                 }
1171         },
1172
1173         /* 
1174          * unique,released vs. group,active
1175          * => should be replaced
1176          */
1177         {
1178                 .line   = __location__,
1179                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1180                 .r1     = {
1181                         .owner          = &ctx->a,
1182                         .type           = WREPL_TYPE_UNIQUE,
1183                         .state          = WREPL_STATE_RELEASED,
1184                         .node           = WREPL_NODE_B,
1185                         .is_static      = False,
1186                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1187                         .ips            = addresses_A_1,
1188                         .apply_expected = False
1189                 },
1190                 .r2     = {
1191                         .owner          = &ctx->b,
1192                         .type           = WREPL_TYPE_GROUP,
1193                         .state          = WREPL_STATE_ACTIVE,
1194                         .node           = WREPL_NODE_B,
1195                         .is_static      = False,
1196                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1197                         .ips            = addresses_B_1,
1198                         .apply_expected = True
1199                 }
1200         },
1201
1202         /* 
1203          * unique,released vs. group,tombstone
1204          * => should be replaced
1205          */
1206         {
1207                 .line   = __location__,
1208                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1209                 .r1     = {
1210                         .owner          = &ctx->b,
1211                         .type           = WREPL_TYPE_UNIQUE,
1212                         .state          = WREPL_STATE_RELEASED,
1213                         .node           = WREPL_NODE_B,
1214                         .is_static      = False,
1215                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1216                         .ips            = addresses_B_1,
1217                         .apply_expected = False
1218                 },
1219                 .r2     = {
1220                         .owner          = &ctx->a,
1221                         .type           = WREPL_TYPE_GROUP,
1222                         .state          = WREPL_STATE_TOMBSTONE,
1223                         .node           = WREPL_NODE_B,
1224                         .is_static      = False,
1225                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1226                         .ips            = addresses_A_1,
1227                         .apply_expected = True
1228                 }
1229         },
1230
1231         /* 
1232          * unique,tombstone vs. group,active
1233          * => should be replaced
1234          */
1235         {
1236                 .line   = __location__,
1237                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1238                 .r1     = {
1239                         .owner          = &ctx->a,
1240                         .type           = WREPL_TYPE_UNIQUE,
1241                         .state          = WREPL_STATE_TOMBSTONE,
1242                         .node           = WREPL_NODE_B,
1243                         .is_static      = False,
1244                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1245                         .ips            = addresses_A_1,
1246                         .apply_expected = True
1247                 },
1248                 .r2     = {
1249                         .owner          = &ctx->b,
1250                         .type           = WREPL_TYPE_GROUP,
1251                         .state          = WREPL_STATE_ACTIVE,
1252                         .node           = WREPL_NODE_B,
1253                         .is_static      = False,
1254                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1255                         .ips            = addresses_B_1,
1256                         .apply_expected = True
1257                 }
1258         },
1259
1260         /* 
1261          * unique,tombstone vs. group,tombstone
1262          * => should be replaced
1263          */
1264         {
1265                 .line   = __location__,
1266                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1267                 .r1     = {
1268                         .owner          = &ctx->b,
1269                         .type           = WREPL_TYPE_UNIQUE,
1270                         .state          = WREPL_STATE_TOMBSTONE,
1271                         .node           = WREPL_NODE_B,
1272                         .is_static      = False,
1273                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1274                         .ips            = addresses_B_1,
1275                         .apply_expected = True
1276                 },
1277                 .r2     = {
1278                         .owner          = &ctx->a,
1279                         .type           = WREPL_TYPE_GROUP,
1280                         .state          = WREPL_STATE_TOMBSTONE,
1281                         .node           = WREPL_NODE_B,
1282                         .is_static      = False,
1283                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1284                         .ips            = addresses_A_1,
1285                         .apply_expected = True
1286                 }
1287         },
1288
1289 /*
1290  * unique vs special groups section,
1291  */
1292         /* 
1293          * unique,active vs. sgroup,active
1294          * => should NOT be replaced
1295          */
1296         {
1297                 .line   = __location__,
1298                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1299                 .r1     = {
1300                         .owner          = &ctx->a,
1301                         .type           = WREPL_TYPE_UNIQUE,
1302                         .state          = WREPL_STATE_ACTIVE,
1303                         .node           = WREPL_NODE_B,
1304                         .is_static      = False,
1305                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1306                         .ips            = addresses_A_1,
1307                         .apply_expected = True
1308                 },
1309                 .r2     = {
1310                         .owner          = &ctx->b,
1311                         .type           = WREPL_TYPE_SGROUP,
1312                         .state          = WREPL_STATE_ACTIVE,
1313                         .node           = WREPL_NODE_B,
1314                         .is_static      = False,
1315                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1316                         .ips            = addresses_A_1,
1317                         .apply_expected = False
1318                 }
1319         },
1320
1321         /* 
1322          * unique,active vs. sgroup,tombstone
1323          * => should NOT be replaced
1324          */
1325         {
1326                 .line   = __location__,
1327                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1328                 .r1     = {
1329                         .owner          = &ctx->a,
1330                         .type           = WREPL_TYPE_UNIQUE,
1331                         .state          = WREPL_STATE_ACTIVE,
1332                         .node           = WREPL_NODE_B,
1333                         .is_static      = False,
1334                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1335                         .ips            = addresses_A_1,
1336                         .apply_expected = True
1337                 },
1338                 .r2     = {
1339                         .owner          = &ctx->b,
1340                         .type           = WREPL_TYPE_SGROUP,
1341                         .state          = WREPL_STATE_TOMBSTONE,
1342                         .node           = WREPL_NODE_B,
1343                         .is_static      = False,
1344                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1345                         .ips            = addresses_A_1,
1346                         .apply_expected = False
1347                 }
1348         },
1349
1350         /* 
1351          * unique,released vs. sgroup,active
1352          * => should be replaced
1353          */
1354         {
1355                 .line   = __location__,
1356                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1357                 .r1     = {
1358                         .owner          = &ctx->a,
1359                         .type           = WREPL_TYPE_UNIQUE,
1360                         .state          = WREPL_STATE_RELEASED,
1361                         .node           = WREPL_NODE_B,
1362                         .is_static      = False,
1363                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1364                         .ips            = addresses_A_1,
1365                         .apply_expected = False
1366                 },
1367                 .r2     = {
1368                         .owner          = &ctx->b,
1369                         .type           = WREPL_TYPE_SGROUP,
1370                         .state          = WREPL_STATE_ACTIVE,
1371                         .node           = WREPL_NODE_B,
1372                         .is_static      = False,
1373                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1374                         .ips            = addresses_B_3_4,
1375                         .apply_expected = True
1376                 }
1377         },
1378
1379         /* 
1380          * unique,released vs. sgroup,tombstone
1381          * => should be replaced
1382          */
1383         {
1384                 .line   = __location__,
1385                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1386                 .r1     = {
1387                         .owner          = &ctx->b,
1388                         .type           = WREPL_TYPE_UNIQUE,
1389                         .state          = WREPL_STATE_RELEASED,
1390                         .node           = WREPL_NODE_B,
1391                         .is_static      = False,
1392                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1393                         .ips            = addresses_B_1,
1394                         .apply_expected = False
1395                 },
1396                 .r2     = {
1397                         .owner          = &ctx->a,
1398                         .type           = WREPL_TYPE_SGROUP,
1399                         .state          = WREPL_STATE_TOMBSTONE,
1400                         .node           = WREPL_NODE_B,
1401                         .is_static      = False,
1402                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
1403                         .ips            = addresses_A_3_4,
1404                         .apply_expected = True
1405                 }
1406         },
1407
1408         /* 
1409          * unique,tombstone vs. sgroup,active
1410          * => should be replaced
1411          */
1412         {
1413                 .line   = __location__,
1414                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1415                 .r1     = {
1416                         .owner          = &ctx->a,
1417                         .type           = WREPL_TYPE_UNIQUE,
1418                         .state          = WREPL_STATE_TOMBSTONE,
1419                         .node           = WREPL_NODE_B,
1420                         .is_static      = False,
1421                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1422                         .ips            = addresses_A_1,
1423                         .apply_expected = True
1424                 },
1425                 .r2     = {
1426                         .owner          = &ctx->b,
1427                         .type           = WREPL_TYPE_SGROUP,
1428                         .state          = WREPL_STATE_ACTIVE,
1429                         .node           = WREPL_NODE_B,
1430                         .is_static      = False,
1431                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1432                         .ips            = addresses_B_3_4,
1433                         .apply_expected = True
1434                 }
1435         },
1436
1437         /* 
1438          * unique,tombstone vs. sgroup,tombstone
1439          * => should be replaced
1440          */
1441         {
1442                 .line   = __location__,
1443                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1444                 .r1     = {
1445                         .owner          = &ctx->b,
1446                         .type           = WREPL_TYPE_UNIQUE,
1447                         .state          = WREPL_STATE_TOMBSTONE,
1448                         .node           = WREPL_NODE_B,
1449                         .is_static      = False,
1450                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1451                         .ips            = addresses_B_1,
1452                         .apply_expected = True
1453                 },
1454                 .r2     = {
1455                         .owner          = &ctx->a,
1456                         .type           = WREPL_TYPE_SGROUP,
1457                         .state          = WREPL_STATE_TOMBSTONE,
1458                         .node           = WREPL_NODE_B,
1459                         .is_static      = False,
1460                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
1461                         .ips            = addresses_A_3_4,
1462                         .apply_expected = True
1463                 }
1464         },
1465
1466 /*
1467  * unique vs multi homed section,
1468  */
1469         /* 
1470          * unique,active vs. mhomed,active
1471          * => should be replaced
1472          */
1473         {
1474                 .line   = __location__,
1475                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1476                 .r1     = {
1477                         .owner          = &ctx->a,
1478                         .type           = WREPL_TYPE_UNIQUE,
1479                         .state          = WREPL_STATE_ACTIVE,
1480                         .node           = WREPL_NODE_B,
1481                         .is_static      = False,
1482                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1483                         .ips            = addresses_A_1,
1484                         .apply_expected = True
1485                 },
1486                 .r2     = {
1487                         .owner          = &ctx->b,
1488                         .type           = WREPL_TYPE_MHOMED,
1489                         .state          = WREPL_STATE_ACTIVE,
1490                         .node           = WREPL_NODE_B,
1491                         .is_static      = False,
1492                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1493                         .ips            = addresses_B_3_4,
1494                         .apply_expected = True
1495                 }
1496         },
1497
1498         /* 
1499          * unique,active vs. mhomed,tombstone
1500          * => should NOT be replaced
1501          */
1502         {
1503                 .line   = __location__,
1504                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1505                 .r1     = {
1506                         .owner          = &ctx->b,
1507                         .type           = WREPL_TYPE_UNIQUE,
1508                         .state          = WREPL_STATE_ACTIVE,
1509                         .node           = WREPL_NODE_B,
1510                         .is_static      = False,
1511                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1512                         .ips            = addresses_B_3_4,
1513                         .apply_expected = True
1514                 },
1515                 .r2     = {
1516                         .owner          = &ctx->a,
1517                         .type           = WREPL_TYPE_MHOMED,
1518                         .state          = WREPL_STATE_TOMBSTONE,
1519                         .node           = WREPL_NODE_B,
1520                         .is_static      = False,
1521                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1522                         .ips            = addresses_B_3_4,
1523                         .apply_expected = False
1524                 }
1525         },
1526
1527         /* 
1528          * unique,released vs. mhomed,active
1529          * => should be replaced
1530          */
1531         {
1532                 .line   = __location__,
1533                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1534                 .r1     = {
1535                         .owner          = &ctx->b,
1536                         .type           = WREPL_TYPE_UNIQUE,
1537                         .state          = WREPL_STATE_RELEASED,
1538                         .node           = WREPL_NODE_B,
1539                         .is_static      = False,
1540                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1541                         .ips            = addresses_B_1,
1542                         .apply_expected = False
1543                 },
1544                 .r2     = {
1545                         .owner          = &ctx->a,
1546                         .type           = WREPL_TYPE_MHOMED,
1547                         .state          = WREPL_STATE_ACTIVE,
1548                         .node           = WREPL_NODE_B,
1549                         .is_static      = False,
1550                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
1551                         .ips            = addresses_A_3_4,
1552                         .apply_expected = True
1553                 }
1554         },
1555
1556         /* 
1557          * unique,released vs. mhomed,tombstone
1558          * => should be replaced
1559          */
1560         {
1561                 .line   = __location__,
1562                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1563                 .r1     = {
1564                         .owner          = &ctx->a,
1565                         .type           = WREPL_TYPE_UNIQUE,
1566                         .state          = WREPL_STATE_RELEASED,
1567                         .node           = WREPL_NODE_B,
1568                         .is_static      = False,
1569                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1570                         .ips            = addresses_A_1,
1571                         .apply_expected = False
1572                 },
1573                 .r2     = {
1574                         .owner          = &ctx->b,
1575                         .type           = WREPL_TYPE_MHOMED,
1576                         .state          = WREPL_STATE_TOMBSTONE,
1577                         .node           = WREPL_NODE_B,
1578                         .is_static      = False,
1579                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1580                         .ips            = addresses_B_3_4,
1581                         .apply_expected = True
1582                 }
1583         },
1584
1585         /* 
1586          * unique,tombstone vs. mhomed,active
1587          * => should be replaced
1588          */
1589         {
1590                 .line   = __location__,
1591                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1592                 .r1     = {
1593                         .owner          = &ctx->b,
1594                         .type           = WREPL_TYPE_UNIQUE,
1595                         .state          = WREPL_STATE_TOMBSTONE,
1596                         .node           = WREPL_NODE_B,
1597                         .is_static      = False,
1598                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1599                         .ips            = addresses_B_1,
1600                         .apply_expected = True
1601                 },
1602                 .r2     = {
1603                         .owner          = &ctx->a,
1604                         .type           = WREPL_TYPE_MHOMED,
1605                         .state          = WREPL_STATE_ACTIVE,
1606                         .node           = WREPL_NODE_B,
1607                         .is_static      = False,
1608                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
1609                         .ips            = addresses_A_3_4,
1610                         .apply_expected = True
1611                 }
1612         },
1613
1614         /* 
1615          * unique,tombstone vs. mhomed,tombstone
1616          * => should be replaced
1617          */
1618         {
1619                 .line   = __location__,
1620                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1621                 .r1     = {
1622                         .owner          = &ctx->a,
1623                         .type           = WREPL_TYPE_UNIQUE,
1624                         .state          = WREPL_STATE_TOMBSTONE,
1625                         .node           = WREPL_NODE_B,
1626                         .is_static      = False,
1627                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1628                         .ips            = addresses_A_1,
1629                         .apply_expected = True
1630                 },
1631                 .r2     = {
1632                         .owner          = &ctx->b,
1633                         .type           = WREPL_TYPE_MHOMED,
1634                         .state          = WREPL_STATE_TOMBSTONE,
1635                         .node           = WREPL_NODE_B,
1636                         .is_static      = False,
1637                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
1638                         .ips            = addresses_B_3_4,
1639                         .apply_expected = True
1640                 }
1641         },
1642
1643 /*
1644  * normal groups vs unique section,
1645  */
1646         /* 
1647          * group,active vs. unique,active
1648          * => should NOT be replaced
1649          */
1650         {
1651                 .line   = __location__,
1652                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1653                 .r1     = {
1654                         .owner          = &ctx->a,
1655                         .type           = WREPL_TYPE_GROUP,
1656                         .state          = WREPL_STATE_ACTIVE,
1657                         .node           = WREPL_NODE_B,
1658                         .is_static      = False,
1659                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1660                         .ips            = addresses_A_1,
1661                         .apply_expected = True
1662                 },
1663                 .r2     = {
1664                         .owner          = &ctx->b,
1665                         .type           = WREPL_TYPE_UNIQUE,
1666                         .state          = WREPL_STATE_ACTIVE,
1667                         .node           = WREPL_NODE_B,
1668                         .is_static      = False,
1669                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1670                         .ips            = addresses_A_1,
1671                         .apply_expected = False
1672                 }
1673         },
1674
1675         /* 
1676          * group,active vs. unique,tombstone
1677          * => should NOT be replaced
1678          */
1679         {
1680                 .line   = __location__,
1681                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1682                 .r1     = {
1683                         .owner          = &ctx->a,
1684                         .type           = WREPL_TYPE_GROUP,
1685                         .state          = WREPL_STATE_ACTIVE,
1686                         .node           = WREPL_NODE_B,
1687                         .is_static      = False,
1688                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1689                         .ips            = addresses_A_1,
1690                         .apply_expected = True
1691                 },
1692                 .r2     = {
1693                         .owner          = &ctx->b,
1694                         .type           = WREPL_TYPE_UNIQUE,
1695                         .state          = WREPL_STATE_TOMBSTONE,
1696                         .node           = WREPL_NODE_B,
1697                         .is_static      = False,
1698                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1699                         .ips            = addresses_A_1,
1700                         .apply_expected = False
1701                 }
1702         },
1703
1704         /* 
1705          * group,released vs. unique,active
1706          * => should NOT be replaced
1707          */
1708         {
1709                 .line   = __location__,
1710                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1711                 .r1     = {
1712                         .owner          = &ctx->a,
1713                         .type           = WREPL_TYPE_GROUP,
1714                         .state          = WREPL_STATE_RELEASED,
1715                         .node           = WREPL_NODE_B,
1716                         .is_static      = False,
1717                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1718                         .ips            = addresses_A_1,
1719                         .apply_expected = False
1720                 },
1721                 .r2     = {
1722                         .owner          = &ctx->b,
1723                         .type           = WREPL_TYPE_UNIQUE,
1724                         .state          = WREPL_STATE_ACTIVE,
1725                         .node           = WREPL_NODE_B,
1726                         .is_static      = False,
1727                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1728                         .ips            = addresses_A_1,
1729                         .apply_expected = False
1730                 }
1731         },
1732
1733         /* 
1734          * group,released vs. unique,tombstone
1735          * => should NOT be replaced
1736          */
1737         {
1738                 .line   = __location__,
1739                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1740                 .r1     = {
1741                         .owner          = &ctx->a,
1742                         .type           = WREPL_TYPE_GROUP,
1743                         .state          = WREPL_STATE_RELEASED,
1744                         .node           = WREPL_NODE_B,
1745                         .is_static      = False,
1746                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1747                         .ips            = addresses_A_1,
1748                         .apply_expected = False
1749                 },
1750                 .r2     = {
1751                         .owner          = &ctx->b,
1752                         .type           = WREPL_TYPE_UNIQUE,
1753                         .state          = WREPL_STATE_TOMBSTONE,
1754                         .node           = WREPL_NODE_B,
1755                         .is_static      = False,
1756                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1757                         .ips            = addresses_A_1,
1758                         .apply_expected = False
1759                 }
1760         },
1761
1762         /* 
1763          * group,tombstone vs. unique,active
1764          * => should NOT be replaced
1765          */
1766         {
1767                 .line   = __location__,
1768                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1769                 .r1     = {
1770                         .owner          = &ctx->a,
1771                         .type           = WREPL_TYPE_GROUP,
1772                         .state          = WREPL_STATE_TOMBSTONE,
1773                         .node           = WREPL_NODE_B,
1774                         .is_static      = False,
1775                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1776                         .ips            = addresses_A_1,
1777                         .apply_expected = True
1778                 },
1779                 .r2     = {
1780                         .owner          = &ctx->b,
1781                         .type           = WREPL_TYPE_UNIQUE,
1782                         .state          = WREPL_STATE_ACTIVE,
1783                         .node           = WREPL_NODE_B,
1784                         .is_static      = False,
1785                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1786                         .ips            = addresses_A_1,
1787                         .apply_expected = False
1788                 }
1789         },
1790
1791         /* 
1792          * group,tombstone vs. unique,tombstone
1793          * => should NOT be replaced
1794          */
1795         {
1796                 .line   = __location__,
1797                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1798                 .r1     = {
1799                         .owner          = &ctx->a,
1800                         .type           = WREPL_TYPE_GROUP,
1801                         .state          = WREPL_STATE_TOMBSTONE,
1802                         .node           = WREPL_NODE_B,
1803                         .is_static      = False,
1804                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1805                         .ips            = addresses_A_1,
1806                         .apply_expected = True
1807                 },
1808                 .r2     = {
1809                         .owner          = &ctx->b,
1810                         .type           = WREPL_TYPE_UNIQUE,
1811                         .state          = WREPL_STATE_TOMBSTONE,
1812                         .node           = WREPL_NODE_B,
1813                         .is_static      = False,
1814                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1815                         .ips            = addresses_A_1,
1816                         .apply_expected = False
1817                 }
1818         },
1819
1820 /*
1821  * normal groups vs normal groups section,
1822  */
1823         /* 
1824          * group,active vs. group,active
1825          * => should NOT be replaced
1826          */
1827         {
1828                 .line   = __location__,
1829                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1830                 .r1     = {
1831                         .owner          = &ctx->a,
1832                         .type           = WREPL_TYPE_GROUP,
1833                         .state          = WREPL_STATE_ACTIVE,
1834                         .node           = WREPL_NODE_B,
1835                         .is_static      = False,
1836                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1837                         .ips            = addresses_A_1,
1838                         .apply_expected = True
1839                 },
1840                 .r2     = {
1841                         .owner          = &ctx->b,
1842                         .type           = WREPL_TYPE_GROUP,
1843                         .state          = WREPL_STATE_ACTIVE,
1844                         .node           = WREPL_NODE_B,
1845                         .is_static      = False,
1846                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1847                         .ips            = addresses_A_1,
1848                         .apply_expected = False
1849                 }
1850         },
1851
1852         /* 
1853          * group,active vs. group,tombstone
1854          * => should NOT be replaced
1855          */
1856         {
1857                 .line   = __location__,
1858                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1859                 .r1     = {
1860                         .owner          = &ctx->a,
1861                         .type           = WREPL_TYPE_GROUP,
1862                         .state          = WREPL_STATE_ACTIVE,
1863                         .node           = WREPL_NODE_B,
1864                         .is_static      = False,
1865                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1866                         .ips            = addresses_A_1,
1867                         .apply_expected = True
1868                 },
1869                 .r2     = {
1870                         .owner          = &ctx->b,
1871                         .type           = WREPL_TYPE_GROUP,
1872                         .state          = WREPL_STATE_TOMBSTONE,
1873                         .node           = WREPL_NODE_B,
1874                         .is_static      = False,
1875                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1876                         .ips            = addresses_A_1,
1877                         .apply_expected = False
1878                 }
1879         },
1880
1881         /* 
1882          * group,released vs. group,active
1883          * => should be replaced
1884          */
1885         {
1886                 .line   = __location__,
1887                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1888                 .r1     = {
1889                         .owner          = &ctx->a,
1890                         .type           = WREPL_TYPE_GROUP,
1891                         .state          = WREPL_STATE_RELEASED,
1892                         .node           = WREPL_NODE_B,
1893                         .is_static      = False,
1894                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1895                         .ips            = addresses_A_1,
1896                         .apply_expected = False
1897                 },
1898                 .r2     = {
1899                         .owner          = &ctx->b,
1900                         .type           = WREPL_TYPE_GROUP,
1901                         .state          = WREPL_STATE_ACTIVE,
1902                         .node           = WREPL_NODE_B,
1903                         .is_static      = False,
1904                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1905                         .ips            = addresses_B_1,
1906                         .apply_expected = True
1907                 }
1908         },
1909
1910         /* 
1911          * group,released vs. group,tombstone
1912          * => should be replaced
1913          */
1914         {
1915                 .line   = __location__,
1916                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1917                 .r1     = {
1918                         .owner          = &ctx->a,
1919                         .type           = WREPL_TYPE_GROUP,
1920                         .state          = WREPL_STATE_RELEASED,
1921                         .node           = WREPL_NODE_B,
1922                         .is_static      = False,
1923                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1924                         .ips            = addresses_A_1,
1925                         .apply_expected = False
1926                 },
1927                 .r2     = {
1928                         .owner          = &ctx->b,
1929                         .type           = WREPL_TYPE_GROUP,
1930                         .state          = WREPL_STATE_TOMBSTONE,
1931                         .node           = WREPL_NODE_B,
1932                         .is_static      = False,
1933                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1934                         .ips            = addresses_B_1,
1935                         .apply_expected = True
1936                 }
1937         },
1938
1939         /* 
1940          * group,tombstone vs. group,active
1941          * => should be replaced
1942          */
1943         {
1944                 .line   = __location__,
1945                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1946                 .r1     = {
1947                         .owner          = &ctx->b,
1948                         .type           = WREPL_TYPE_GROUP,
1949                         .state          = WREPL_STATE_TOMBSTONE,
1950                         .node           = WREPL_NODE_B,
1951                         .is_static      = False,
1952                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1953                         .ips            = addresses_B_1,
1954                         .apply_expected = True
1955                 },
1956                 .r2     = {
1957                         .owner          = &ctx->a,
1958                         .type           = WREPL_TYPE_GROUP,
1959                         .state          = WREPL_STATE_ACTIVE,
1960                         .node           = WREPL_NODE_B,
1961                         .is_static      = False,
1962                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1963                         .ips            = addresses_A_1,
1964                         .apply_expected = True
1965                 }
1966         },
1967
1968         /* 
1969          * group,tombstone vs. group,tombstone
1970          * => should be replaced
1971          */
1972         {
1973                 .line   = __location__,
1974                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1975                 .r1     = {
1976                         .owner          = &ctx->a,
1977                         .type           = WREPL_TYPE_GROUP,
1978                         .state          = WREPL_STATE_TOMBSTONE,
1979                         .node           = WREPL_NODE_B,
1980                         .is_static      = False,
1981                         .num_ips        = ARRAY_SIZE(addresses_A_1),
1982                         .ips            = addresses_A_1,
1983                         .apply_expected = True
1984                 },
1985                 .r2     = {
1986                         .owner          = &ctx->b,
1987                         .type           = WREPL_TYPE_GROUP,
1988                         .state          = WREPL_STATE_TOMBSTONE,
1989                         .node           = WREPL_NODE_B,
1990                         .is_static      = False,
1991                         .num_ips        = ARRAY_SIZE(addresses_B_1),
1992                         .ips            = addresses_B_1,
1993                         .apply_expected = True
1994                 }
1995         },
1996
1997 /*
1998  * normal groups vs special groups section,
1999  */
2000         /* 
2001          * group,active vs. sgroup,active
2002          * => should NOT be replaced
2003          */
2004         {
2005                 .line   = __location__,
2006                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2007                 .r1     = {
2008                         .owner          = &ctx->b,
2009                         .type           = WREPL_TYPE_GROUP,
2010                         .state          = WREPL_STATE_ACTIVE,
2011                         .node           = WREPL_NODE_B,
2012                         .is_static      = False,
2013                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2014                         .ips            = addresses_B_1,
2015                         .apply_expected = True
2016                 },
2017                 .r2     = {
2018                         .owner          = &ctx->a,
2019                         .type           = WREPL_TYPE_SGROUP,
2020                         .state          = WREPL_STATE_ACTIVE,
2021                         .node           = WREPL_NODE_B,
2022                         .is_static      = False,
2023                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2024                         .ips            = addresses_B_1,
2025                         .apply_expected = False
2026                 }
2027         },
2028
2029         /* 
2030          * group,active vs. sgroup,tombstone
2031          * => should NOT be replaced
2032          */
2033         {
2034                 .line   = __location__,
2035                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2036                 .r1     = {
2037                         .owner          = &ctx->b,
2038                         .type           = WREPL_TYPE_GROUP,
2039                         .state          = WREPL_STATE_ACTIVE,
2040                         .node           = WREPL_NODE_B,
2041                         .is_static      = False,
2042                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2043                         .ips            = addresses_B_1,
2044                         .apply_expected = True
2045                 },
2046                 .r2     = {
2047                         .owner          = &ctx->a,
2048                         .type           = WREPL_TYPE_SGROUP,
2049                         .state          = WREPL_STATE_TOMBSTONE,
2050                         .node           = WREPL_NODE_B,
2051                         .is_static      = False,
2052                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2053                         .ips            = addresses_B_1,
2054                         .apply_expected = False
2055                 }
2056         },
2057
2058         /* 
2059          * group,released vs. sgroup,active
2060          * => should be replaced
2061          */
2062         {
2063                 .line   = __location__,
2064                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2065                 .r1     = {
2066                         .owner          = &ctx->a,
2067                         .type           = WREPL_TYPE_GROUP,
2068                         .state          = WREPL_STATE_RELEASED,
2069                         .node           = WREPL_NODE_B,
2070                         .is_static      = False,
2071                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2072                         .ips            = addresses_A_1,
2073                         .apply_expected = False
2074                 },
2075                 .r2     = {
2076                         .owner          = &ctx->b,
2077                         .type           = WREPL_TYPE_SGROUP,
2078                         .state          = WREPL_STATE_ACTIVE,
2079                         .node           = WREPL_NODE_B,
2080                         .is_static      = False,
2081                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2082                         .ips            = addresses_B_1,
2083                         .apply_expected = True
2084                 }
2085         },
2086
2087         /* 
2088          * group,released vs. sgroup,tombstone
2089          * => should NOT be replaced
2090          */
2091         {
2092                 .line   = __location__,
2093                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2094                 .r1     = {
2095                         .owner          = &ctx->b,
2096                         .type           = WREPL_TYPE_GROUP,
2097                         .state          = WREPL_STATE_RELEASED,
2098                         .node           = WREPL_NODE_B,
2099                         .is_static      = False,
2100                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2101                         .ips            = addresses_B_1,
2102                         .apply_expected = False
2103                 },
2104                 .r2     = {
2105                         .owner          = &ctx->a,
2106                         .type           = WREPL_TYPE_SGROUP,
2107                         .state          = WREPL_STATE_TOMBSTONE,
2108                         .node           = WREPL_NODE_B,
2109                         .is_static      = False,
2110                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2111                         .ips            = addresses_B_1,
2112                         .apply_expected = False
2113                 }
2114         },
2115
2116         /* 
2117          * group,tombstone vs. sgroup,active
2118          * => should be replaced
2119          */
2120         {
2121                 .line   = __location__,
2122                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2123                 .r1     = {
2124                         .owner          = &ctx->b,
2125                         .type           = WREPL_TYPE_GROUP,
2126                         .state          = WREPL_STATE_TOMBSTONE,
2127                         .node           = WREPL_NODE_B,
2128                         .is_static      = False,
2129                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2130                         .ips            = addresses_B_1,
2131                         .apply_expected = True
2132                 },
2133                 .r2     = {
2134                         .owner          = &ctx->a,
2135                         .type           = WREPL_TYPE_SGROUP,
2136                         .state          = WREPL_STATE_ACTIVE,
2137                         .node           = WREPL_NODE_B,
2138                         .is_static      = False,
2139                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2140                         .ips            = addresses_A_1,
2141                         .apply_expected = True
2142                 }
2143         },
2144
2145         /* 
2146          * group,tombstone vs. sgroup,tombstone
2147          * => should be replaced
2148          */
2149         {
2150                 .line   = __location__,
2151                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2152                 .r1     = {
2153                         .owner          = &ctx->a,
2154                         .type           = WREPL_TYPE_GROUP,
2155                         .state          = WREPL_STATE_TOMBSTONE,
2156                         .node           = WREPL_NODE_B,
2157                         .is_static      = False,
2158                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2159                         .ips            = addresses_A_1,
2160                         .apply_expected = True
2161                 },
2162                 .r2     = {
2163                         .owner          = &ctx->b,
2164                         .type           = WREPL_TYPE_SGROUP,
2165                         .state          = WREPL_STATE_TOMBSTONE,
2166                         .node           = WREPL_NODE_B,
2167                         .is_static      = False,
2168                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2169                         .ips            = addresses_B_1,
2170                         .apply_expected = True
2171                 }
2172         },
2173
2174 /*
2175  * normal groups vs multi homed section,
2176  */
2177         /* 
2178          * group,active vs. mhomed,active
2179          * => should NOT be replaced
2180          */
2181         {
2182                 .line   = __location__,
2183                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2184                 .r1     = {
2185                         .owner          = &ctx->b,
2186                         .type           = WREPL_TYPE_GROUP,
2187                         .state          = WREPL_STATE_ACTIVE,
2188                         .node           = WREPL_NODE_B,
2189                         .is_static      = False,
2190                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2191                         .ips            = addresses_B_1,
2192                         .apply_expected = True
2193                 },
2194                 .r2     = {
2195                         .owner          = &ctx->a,
2196                         .type           = WREPL_TYPE_MHOMED,
2197                         .state          = WREPL_STATE_ACTIVE,
2198                         .node           = WREPL_NODE_B,
2199                         .is_static      = False,
2200                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2201                         .ips            = addresses_B_1,
2202                         .apply_expected = False
2203                 }
2204         },
2205
2206         /* 
2207          * group,active vs. mhomed,tombstone
2208          * => should NOT be replaced
2209          */
2210         {
2211                 .line   = __location__,
2212                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2213                 .r1     = {
2214                         .owner          = &ctx->b,
2215                         .type           = WREPL_TYPE_GROUP,
2216                         .state          = WREPL_STATE_ACTIVE,
2217                         .node           = WREPL_NODE_B,
2218                         .is_static      = False,
2219                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2220                         .ips            = addresses_B_1,
2221                         .apply_expected = True
2222                 },
2223                 .r2     = {
2224                         .owner          = &ctx->a,
2225                         .type           = WREPL_TYPE_MHOMED,
2226                         .state          = WREPL_STATE_TOMBSTONE,
2227                         .node           = WREPL_NODE_B,
2228                         .is_static      = False,
2229                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2230                         .ips            = addresses_B_1,
2231                         .apply_expected = False
2232                 }
2233         },
2234
2235         /* 
2236          * group,released vs. mhomed,active
2237          * => should NOT be replaced
2238          */
2239         {
2240                 .line   = __location__,
2241                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2242                 .r1     = {
2243                         .owner          = &ctx->b,
2244                         .type           = WREPL_TYPE_GROUP,
2245                         .state          = WREPL_STATE_RELEASED,
2246                         .node           = WREPL_NODE_B,
2247                         .is_static      = False,
2248                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2249                         .ips            = addresses_B_1,
2250                         .apply_expected = False
2251                 },
2252                 .r2     = {
2253                         .owner          = &ctx->a,
2254                         .type           = WREPL_TYPE_MHOMED,
2255                         .state          = WREPL_STATE_ACTIVE,
2256                         .node           = WREPL_NODE_B,
2257                         .is_static      = False,
2258                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2259                         .ips            = addresses_B_1,
2260                         .apply_expected = False
2261                 }
2262         },
2263
2264         /* 
2265          * group,released vs. mhomed,tombstone
2266          * => should NOT be replaced
2267          */
2268         {
2269                 .line   = __location__,
2270                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2271                 .r1     = {
2272                         .owner          = &ctx->b,
2273                         .type           = WREPL_TYPE_GROUP,
2274                         .state          = WREPL_STATE_RELEASED,
2275                         .node           = WREPL_NODE_B,
2276                         .is_static      = False,
2277                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2278                         .ips            = addresses_B_1,
2279                         .apply_expected = False
2280                 },
2281                 .r2     = {
2282                         .owner          = &ctx->a,
2283                         .type           = WREPL_TYPE_MHOMED,
2284                         .state          = WREPL_STATE_TOMBSTONE,
2285                         .node           = WREPL_NODE_B,
2286                         .is_static      = False,
2287                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2288                         .ips            = addresses_B_1,
2289                         .apply_expected = False
2290                 }
2291         },
2292
2293         /* 
2294          * group,tombstone vs. mhomed,active
2295          * => should be replaced
2296          */
2297         {
2298                 .line   = __location__,
2299                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2300                 .r1     = {
2301                         .owner          = &ctx->b,
2302                         .type           = WREPL_TYPE_GROUP,
2303                         .state          = WREPL_STATE_TOMBSTONE,
2304                         .node           = WREPL_NODE_B,
2305                         .is_static      = False,
2306                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2307                         .ips            = addresses_B_1,
2308                         .apply_expected = True
2309                 },
2310                 .r2     = {
2311                         .owner          = &ctx->a,
2312                         .type           = WREPL_TYPE_MHOMED,
2313                         .state          = WREPL_STATE_ACTIVE,
2314                         .node           = WREPL_NODE_B,
2315                         .is_static      = False,
2316                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2317                         .ips            = addresses_A_1,
2318                         .apply_expected = True
2319                 }
2320         },
2321
2322         /* 
2323          * group,tombstone vs. mhomed,tombstone
2324          * => should be replaced
2325          */
2326         {
2327                 .line   = __location__,
2328                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2329                 .r1     = {
2330                         .owner          = &ctx->a,
2331                         .type           = WREPL_TYPE_GROUP,
2332                         .state          = WREPL_STATE_TOMBSTONE,
2333                         .node           = WREPL_NODE_B,
2334                         .is_static      = False,
2335                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2336                         .ips            = addresses_A_1,
2337                         .apply_expected = True
2338                 },
2339                 .r2     = {
2340                         .owner          = &ctx->b,
2341                         .type           = WREPL_TYPE_MHOMED,
2342                         .state          = WREPL_STATE_TOMBSTONE,
2343                         .node           = WREPL_NODE_B,
2344                         .is_static      = False,
2345                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2346                         .ips            = addresses_B_1,
2347                         .apply_expected = True
2348                 }
2349         },
2350
2351 /*
2352  * special groups vs unique section,
2353  */
2354         /* 
2355          * sgroup,active vs. unique,active
2356          * => should NOT be replaced
2357          */
2358         {
2359                 .line   = __location__,
2360                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2361                 .r1     = {
2362                         .owner          = &ctx->b,
2363                         .type           = WREPL_TYPE_SGROUP,
2364                         .state          = WREPL_STATE_ACTIVE,
2365                         .node           = WREPL_NODE_B,
2366                         .is_static      = False,
2367                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2368                         .ips            = addresses_B_1,
2369                         .apply_expected = True
2370                 },
2371                 .r2     = {
2372                         .owner          = &ctx->a,
2373                         .type           = WREPL_TYPE_UNIQUE,
2374                         .state          = WREPL_STATE_ACTIVE,
2375                         .node           = WREPL_NODE_B,
2376                         .is_static      = False,
2377                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2378                         .ips            = addresses_B_1,
2379                         .apply_expected = False
2380                 }
2381         },
2382
2383         /* 
2384          * sgroup,active vs. unique,tombstone
2385          * => should NOT be replaced
2386          */
2387         {
2388                 .line   = __location__,
2389                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2390                 .r1     = {
2391                         .owner          = &ctx->b,
2392                         .type           = WREPL_TYPE_SGROUP,
2393                         .state          = WREPL_STATE_ACTIVE,
2394                         .node           = WREPL_NODE_B,
2395                         .is_static      = False,
2396                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2397                         .ips            = addresses_B_1,
2398                         .apply_expected = True
2399                 },
2400                 .r2     = {
2401                         .owner          = &ctx->a,
2402                         .type           = WREPL_TYPE_UNIQUE,
2403                         .state          = WREPL_STATE_TOMBSTONE,
2404                         .node           = WREPL_NODE_B,
2405                         .is_static      = False,
2406                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2407                         .ips            = addresses_B_1,
2408                         .apply_expected = False
2409                 }
2410         },
2411
2412         /* 
2413          * sgroup,released vs. unique,active
2414          * => should be replaced
2415          */
2416         {
2417                 .line   = __location__,
2418                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2419                 .r1     = {
2420                         .owner          = &ctx->b,
2421                         .type           = WREPL_TYPE_SGROUP,
2422                         .state          = WREPL_STATE_RELEASED,
2423                         .node           = WREPL_NODE_B,
2424                         .is_static      = False,
2425                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2426                         .ips            = addresses_B_1,
2427                         .apply_expected = False
2428                 },
2429                 .r2     = {
2430                         .owner          = &ctx->a,
2431                         .type           = WREPL_TYPE_UNIQUE,
2432                         .state          = WREPL_STATE_ACTIVE,
2433                         .node           = WREPL_NODE_B,
2434                         .is_static      = False,
2435                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2436                         .ips            = addresses_A_1,
2437                         .apply_expected = True
2438                 }
2439         },
2440
2441         /* 
2442          * sgroup,released vs. unique,tombstone
2443          * => should be replaced
2444          */
2445         {
2446                 .line   = __location__,
2447                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2448                 .r1     = {
2449                         .owner          = &ctx->a,
2450                         .type           = WREPL_TYPE_SGROUP,
2451                         .state          = WREPL_STATE_RELEASED,
2452                         .node           = WREPL_NODE_B,
2453                         .is_static      = False,
2454                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2455                         .ips            = addresses_A_1,
2456                         .apply_expected = False
2457                 },
2458                 .r2     = {
2459                         .owner          = &ctx->b,
2460                         .type           = WREPL_TYPE_UNIQUE,
2461                         .state          = WREPL_STATE_TOMBSTONE,
2462                         .node           = WREPL_NODE_B,
2463                         .is_static      = False,
2464                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2465                         .ips            = addresses_B_1,
2466                         .apply_expected = True
2467                 }
2468         },
2469
2470         /* 
2471          * sgroup,tombstone vs. unique,active
2472          * => should be replaced
2473          */
2474         {
2475                 .line   = __location__,
2476                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2477                 .r1     = {
2478                         .owner          = &ctx->a,
2479                         .type           = WREPL_TYPE_SGROUP,
2480                         .state          = WREPL_STATE_TOMBSTONE,
2481                         .node           = WREPL_NODE_B,
2482                         .is_static      = False,
2483                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2484                         .ips            = addresses_A_1,
2485                         .apply_expected = True
2486                 },
2487                 .r2     = {
2488                         .owner          = &ctx->b,
2489                         .type           = WREPL_TYPE_UNIQUE,
2490                         .state          = WREPL_STATE_ACTIVE,
2491                         .node           = WREPL_NODE_B,
2492                         .is_static      = False,
2493                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2494                         .ips            = addresses_B_1,
2495                         .apply_expected = True
2496                 }
2497         },
2498
2499         /* 
2500          * sgroup,tombstone vs. unique,tombstone
2501          * => should be replaced
2502          */
2503         {
2504                 .line   = __location__,
2505                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2506                 .r1     = {
2507                         .owner          = &ctx->b,
2508                         .type           = WREPL_TYPE_SGROUP,
2509                         .state          = WREPL_STATE_TOMBSTONE,
2510                         .node           = WREPL_NODE_B,
2511                         .is_static      = False,
2512                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2513                         .ips            = addresses_B_1,
2514                         .apply_expected = True
2515                 },
2516                 .r2     = {
2517                         .owner          = &ctx->a,
2518                         .type           = WREPL_TYPE_UNIQUE,
2519                         .state          = WREPL_STATE_TOMBSTONE,
2520                         .node           = WREPL_NODE_B,
2521                         .is_static      = False,
2522                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2523                         .ips            = addresses_A_1,
2524                         .apply_expected = True
2525                 }
2526         },
2527
2528 /*
2529  * special groups vs normal group section,
2530  */
2531         /* 
2532          * sgroup,active vs. group,active
2533          * => should NOT be replaced
2534          */
2535         {
2536                 .line   = __location__,
2537                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2538                 .r1     = {
2539                         .owner          = &ctx->a,
2540                         .type           = WREPL_TYPE_SGROUP,
2541                         .state          = WREPL_STATE_ACTIVE,
2542                         .node           = WREPL_NODE_B,
2543                         .is_static      = False,
2544                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2545                         .ips            = addresses_A_1,
2546                         .apply_expected = True
2547                 },
2548                 .r2     = {
2549                         .owner          = &ctx->b,
2550                         .type           = WREPL_TYPE_GROUP,
2551                         .state          = WREPL_STATE_ACTIVE,
2552                         .node           = WREPL_NODE_B,
2553                         .is_static      = False,
2554                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2555                         .ips            = addresses_A_1,
2556                         .apply_expected = False
2557                 }
2558         },
2559
2560         /* 
2561          * sgroup,active vs. group,tombstone
2562          * => should NOT be replaced
2563          */
2564         {
2565                 .line   = __location__,
2566                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2567                 .r1     = {
2568                         .owner          = &ctx->a,
2569                         .type           = WREPL_TYPE_SGROUP,
2570                         .state          = WREPL_STATE_ACTIVE,
2571                         .node           = WREPL_NODE_B,
2572                         .is_static      = False,
2573                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2574                         .ips            = addresses_A_1,
2575                         .apply_expected = True
2576                 },
2577                 .r2     = {
2578                         .owner          = &ctx->b,
2579                         .type           = WREPL_TYPE_GROUP,
2580                         .state          = WREPL_STATE_TOMBSTONE,
2581                         .node           = WREPL_NODE_B,
2582                         .is_static      = False,
2583                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2584                         .ips            = addresses_A_1,
2585                         .apply_expected = False
2586                 }
2587         },
2588
2589         /* 
2590          * sgroup,released vs. group,active
2591          * => should be replaced
2592          */
2593         {
2594                 .line   = __location__,
2595                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2596                 .r1     = {
2597                         .owner          = &ctx->a,
2598                         .type           = WREPL_TYPE_SGROUP,
2599                         .state          = WREPL_STATE_RELEASED,
2600                         .node           = WREPL_NODE_B,
2601                         .is_static      = False,
2602                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2603                         .ips            = addresses_A_1,
2604                         .apply_expected = False
2605                 },
2606                 .r2     = {
2607                         .owner          = &ctx->b,
2608                         .type           = WREPL_TYPE_GROUP,
2609                         .state          = WREPL_STATE_ACTIVE,
2610                         .node           = WREPL_NODE_B,
2611                         .is_static      = False,
2612                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2613                         .ips            = addresses_B_1,
2614                         .apply_expected = True
2615                 }
2616         },
2617
2618         /* 
2619          * sgroup,released vs. group,tombstone
2620          * => should be replaced
2621          */
2622         {
2623                 .line   = __location__,
2624                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2625                 .r1     = {
2626                         .owner          = &ctx->b,
2627                         .type           = WREPL_TYPE_SGROUP,
2628                         .state          = WREPL_STATE_RELEASED,
2629                         .node           = WREPL_NODE_B,
2630                         .is_static      = False,
2631                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2632                         .ips            = addresses_B_1,
2633                         .apply_expected = False
2634                 },
2635                 .r2     = {
2636                         .owner          = &ctx->a,
2637                         .type           = WREPL_TYPE_GROUP,
2638                         .state          = WREPL_STATE_TOMBSTONE,
2639                         .node           = WREPL_NODE_B,
2640                         .is_static      = False,
2641                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2642                         .ips            = addresses_A_1,
2643                         .apply_expected = True
2644                 }
2645         },
2646
2647         /* 
2648          * sgroup,tombstone vs. group,active
2649          * => should NOT be replaced
2650          */
2651         {
2652                 .line   = __location__,
2653                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2654                 .r1     = {
2655                         .owner          = &ctx->a,
2656                         .type           = WREPL_TYPE_SGROUP,
2657                         .state          = WREPL_STATE_TOMBSTONE,
2658                         .node           = WREPL_NODE_B,
2659                         .is_static      = False,
2660                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2661                         .ips            = addresses_A_1,
2662                         .apply_expected = True
2663                 },
2664                 .r2     = {
2665                         .owner          = &ctx->b,
2666                         .type           = WREPL_TYPE_GROUP,
2667                         .state          = WREPL_STATE_ACTIVE,
2668                         .node           = WREPL_NODE_B,
2669                         .is_static      = False,
2670                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2671                         .ips            = addresses_B_1,
2672                         .apply_expected = True
2673                 }
2674         },
2675
2676         /* 
2677          * sgroup,tombstone vs. group,tombstone
2678          * => should NOT be replaced
2679          */
2680         {
2681                 .line   = __location__,
2682                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2683                 .r1     = {
2684                         .owner          = &ctx->b,
2685                         .type           = WREPL_TYPE_SGROUP,
2686                         .state          = WREPL_STATE_TOMBSTONE,
2687                         .node           = WREPL_NODE_B,
2688                         .is_static      = False,
2689                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2690                         .ips            = addresses_B_1,
2691                         .apply_expected = True
2692                 },
2693                 .r2     = {
2694                         .owner          = &ctx->a,
2695                         .type           = WREPL_TYPE_GROUP,
2696                         .state          = WREPL_STATE_TOMBSTONE,
2697                         .node           = WREPL_NODE_B,
2698                         .is_static      = False,
2699                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2700                         .ips            = addresses_A_1,
2701                         .apply_expected = True
2702                 }
2703         },
2704
2705 /*
2706  * special groups vs multi homed section,
2707  */
2708         /* 
2709          * sgroup,active vs. mhomed,active
2710          * => should NOT be replaced
2711          */
2712         {
2713                 .line   = __location__,
2714                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2715                 .r1     = {
2716                         .owner          = &ctx->a,
2717                         .type           = WREPL_TYPE_SGROUP,
2718                         .state          = WREPL_STATE_ACTIVE,
2719                         .node           = WREPL_NODE_B,
2720                         .is_static      = False,
2721                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2722                         .ips            = addresses_A_1,
2723                         .apply_expected = True
2724                 },
2725                 .r2     = {
2726                         .owner          = &ctx->b,
2727                         .type           = WREPL_TYPE_MHOMED,
2728                         .state          = WREPL_STATE_ACTIVE,
2729                         .node           = WREPL_NODE_B,
2730                         .is_static      = False,
2731                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2732                         .ips            = addresses_A_1,
2733                         .apply_expected = False
2734                 }
2735         },
2736
2737         /* 
2738          * sgroup,active vs. mhomed,tombstone
2739          * => should NOT be replaced
2740          */
2741         {
2742                 .line   = __location__,
2743                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2744                 .r1     = {
2745                         .owner          = &ctx->a,
2746                         .type           = WREPL_TYPE_SGROUP,
2747                         .state          = WREPL_STATE_ACTIVE,
2748                         .node           = WREPL_NODE_B,
2749                         .is_static      = False,
2750                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2751                         .ips            = addresses_A_1,
2752                         .apply_expected = True
2753                 },
2754                 .r2     = {
2755                         .owner          = &ctx->b,
2756                         .type           = WREPL_TYPE_MHOMED,
2757                         .state          = WREPL_STATE_TOMBSTONE,
2758                         .node           = WREPL_NODE_B,
2759                         .is_static      = False,
2760                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2761                         .ips            = addresses_A_1,
2762                         .apply_expected = False
2763                 }
2764         },
2765
2766         /* 
2767          * sgroup,released vs. mhomed,active
2768          * => should be replaced
2769          */
2770         {
2771                 .line   = __location__,
2772                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2773                 .r1     = {
2774                         .owner          = &ctx->a,
2775                         .type           = WREPL_TYPE_SGROUP,
2776                         .state          = WREPL_STATE_RELEASED,
2777                         .node           = WREPL_NODE_B,
2778                         .is_static      = False,
2779                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2780                         .ips            = addresses_A_1,
2781                         .apply_expected = False
2782                 },
2783                 .r2     = {
2784                         .owner          = &ctx->b,
2785                         .type           = WREPL_TYPE_MHOMED,
2786                         .state          = WREPL_STATE_ACTIVE,
2787                         .node           = WREPL_NODE_B,
2788                         .is_static      = False,
2789                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2790                         .ips            = addresses_B_1,
2791                         .apply_expected = True
2792                 }
2793         },
2794
2795         /* 
2796          * sgroup,released vs. mhomed,tombstone
2797          * => should be replaced
2798          */
2799         {
2800                 .line   = __location__,
2801                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2802                 .r1     = {
2803                         .owner          = &ctx->b,
2804                         .type           = WREPL_TYPE_SGROUP,
2805                         .state          = WREPL_STATE_RELEASED,
2806                         .node           = WREPL_NODE_B,
2807                         .is_static      = False,
2808                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2809                         .ips            = addresses_B_1,
2810                         .apply_expected = False
2811                 },
2812                 .r2     = {
2813                         .owner          = &ctx->a,
2814                         .type           = WREPL_TYPE_MHOMED,
2815                         .state          = WREPL_STATE_TOMBSTONE,
2816                         .node           = WREPL_NODE_B,
2817                         .is_static      = False,
2818                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2819                         .ips            = addresses_A_1,
2820                         .apply_expected = True
2821                 }
2822         },
2823
2824         /* 
2825          * sgroup,tombstone vs. mhomed,active
2826          * => should be replaced
2827          */
2828         {
2829                 .line   = __location__,
2830                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2831                 .r1     = {
2832                         .owner          = &ctx->a,
2833                         .type           = WREPL_TYPE_SGROUP,
2834                         .state          = WREPL_STATE_TOMBSTONE,
2835                         .node           = WREPL_NODE_B,
2836                         .is_static      = False,
2837                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2838                         .ips            = addresses_A_1,
2839                         .apply_expected = True
2840                 },
2841                 .r2     = {
2842                         .owner          = &ctx->b,
2843                         .type           = WREPL_TYPE_MHOMED,
2844                         .state          = WREPL_STATE_ACTIVE,
2845                         .node           = WREPL_NODE_B,
2846                         .is_static      = False,
2847                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2848                         .ips            = addresses_B_1,
2849                         .apply_expected = True
2850                 }
2851         },
2852
2853         /* 
2854          * sgroup,tombstone vs. mhomed,tombstone
2855          * => should be replaced
2856          */
2857         {
2858                 .line   = __location__,
2859                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2860                 .r1     = {
2861                         .owner          = &ctx->b,
2862                         .type           = WREPL_TYPE_SGROUP,
2863                         .state          = WREPL_STATE_TOMBSTONE,
2864                         .node           = WREPL_NODE_B,
2865                         .is_static      = False,
2866                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2867                         .ips            = addresses_B_1,
2868                         .apply_expected = True
2869                 },
2870                 .r2     = {
2871                         .owner          = &ctx->a,
2872                         .type           = WREPL_TYPE_MHOMED,
2873                         .state          = WREPL_STATE_TOMBSTONE,
2874                         .node           = WREPL_NODE_B,
2875                         .is_static      = False,
2876                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2877                         .ips            = addresses_A_1,
2878                         .apply_expected = True
2879                 }
2880         },
2881
2882 /*
2883  * multi homed vs. unique section,
2884  */
2885         /* 
2886          * mhomed,active vs. unique,active
2887          * => should be replaced
2888          */
2889         {
2890                 .line   = __location__,
2891                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2892                 .r1     = {
2893                         .owner          = &ctx->a,
2894                         .type           = WREPL_TYPE_MHOMED,
2895                         .state          = WREPL_STATE_ACTIVE,
2896                         .node           = WREPL_NODE_B,
2897                         .is_static      = False,
2898                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
2899                         .ips            = addresses_A_3_4,
2900                         .apply_expected = True
2901                 },
2902                 .r2     = {
2903                         .owner          = &ctx->b,
2904                         .type           = WREPL_TYPE_UNIQUE,
2905                         .state          = WREPL_STATE_ACTIVE,
2906                         .node           = WREPL_NODE_B,
2907                         .is_static      = False,
2908                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2909                         .ips            = addresses_B_1,
2910                         .apply_expected = True
2911                 }
2912         },
2913
2914         /* 
2915          * mhomed,active vs. unique,tombstone
2916          * => should NOT be replaced
2917          */
2918         {
2919                 .line   = __location__,
2920                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2921                 .r1     = {
2922                         .owner          = &ctx->b,
2923                         .type           = WREPL_TYPE_MHOMED,
2924                         .state          = WREPL_STATE_ACTIVE,
2925                         .node           = WREPL_NODE_B,
2926                         .is_static      = False,
2927                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2928                         .ips            = addresses_B_1,
2929                         .apply_expected = True
2930                 },
2931                 .r2     = {
2932                         .owner          = &ctx->a,
2933                         .type           = WREPL_TYPE_UNIQUE,
2934                         .state          = WREPL_STATE_TOMBSTONE,
2935                         .node           = WREPL_NODE_B,
2936                         .is_static      = False,
2937                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2938                         .ips            = addresses_B_1,
2939                         .apply_expected = False
2940                 }
2941         },
2942
2943         /* 
2944          * mhomed,released vs. unique,active
2945          * => should be replaced
2946          */
2947         {
2948                 .line   = __location__,
2949                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2950                 .r1     = {
2951                         .owner          = &ctx->a,
2952                         .type           = WREPL_TYPE_MHOMED,
2953                         .state          = WREPL_STATE_RELEASED,
2954                         .node           = WREPL_NODE_B,
2955                         .is_static      = False,
2956                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2957                         .ips            = addresses_A_1,
2958                         .apply_expected = False
2959                 },
2960                 .r2     = {
2961                         .owner          = &ctx->b,
2962                         .type           = WREPL_TYPE_UNIQUE,
2963                         .state          = WREPL_STATE_ACTIVE,
2964                         .node           = WREPL_NODE_B,
2965                         .is_static      = False,
2966                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2967                         .ips            = addresses_B_1,
2968                         .apply_expected = True
2969                 }
2970         },
2971
2972         /* 
2973          * mhomed,released vs. uinique,tombstone
2974          * => should be replaced
2975          */
2976         {
2977                 .line   = __location__,
2978                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2979                 .r1     = {
2980                         .owner          = &ctx->b,
2981                         .type           = WREPL_TYPE_MHOMED,
2982                         .state          = WREPL_STATE_RELEASED,
2983                         .node           = WREPL_NODE_B,
2984                         .is_static      = False,
2985                         .num_ips        = ARRAY_SIZE(addresses_B_1),
2986                         .ips            = addresses_B_1,
2987                         .apply_expected = False
2988                 },
2989                 .r2     = {
2990                         .owner          = &ctx->a,
2991                         .type           = WREPL_TYPE_UNIQUE,
2992                         .state          = WREPL_STATE_TOMBSTONE,
2993                         .node           = WREPL_NODE_B,
2994                         .is_static      = False,
2995                         .num_ips        = ARRAY_SIZE(addresses_A_1),
2996                         .ips            = addresses_A_1,
2997                         .apply_expected = True
2998                 }
2999         },
3000
3001         /* 
3002          * mhomed,tombstone vs. unique,active
3003          * => should be replaced
3004          */
3005         {
3006                 .line   = __location__,
3007                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3008                 .r1     = {
3009                         .owner          = &ctx->a,
3010                         .type           = WREPL_TYPE_MHOMED,
3011                         .state          = WREPL_STATE_TOMBSTONE,
3012                         .node           = WREPL_NODE_B,
3013                         .is_static      = False,
3014                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3015                         .ips            = addresses_A_1,
3016                         .apply_expected = True
3017                 },
3018                 .r2     = {
3019                         .owner          = &ctx->b,
3020                         .type           = WREPL_TYPE_UNIQUE,
3021                         .state          = WREPL_STATE_ACTIVE,
3022                         .node           = WREPL_NODE_B,
3023                         .is_static      = False,
3024                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3025                         .ips            = addresses_B_1,
3026                         .apply_expected = True
3027                 }
3028         },
3029
3030         /* 
3031          * mhomed,tombstone vs. uinique,tombstone
3032          * => should be replaced
3033          */
3034         {
3035                 .line   = __location__,
3036                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3037                 .r1     = {
3038                         .owner          = &ctx->b,
3039                         .type           = WREPL_TYPE_MHOMED,
3040                         .state          = WREPL_STATE_TOMBSTONE,
3041                         .node           = WREPL_NODE_B,
3042                         .is_static      = False,
3043                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3044                         .ips            = addresses_B_1,
3045                         .apply_expected = True
3046                 },
3047                 .r2     = {
3048                         .owner          = &ctx->a,
3049                         .type           = WREPL_TYPE_UNIQUE,
3050                         .state          = WREPL_STATE_TOMBSTONE,
3051                         .node           = WREPL_NODE_B,
3052                         .is_static      = False,
3053                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3054                         .ips            = addresses_A_1,
3055                         .apply_expected = True
3056                 }
3057         },
3058
3059 /*
3060  * multi homed vs. normal group section,
3061  */
3062         /* 
3063          * mhomed,active vs. group,active
3064          * => should be replaced
3065          */
3066         {
3067                 .line   = __location__,
3068                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3069                 .r1     = {
3070                         .owner          = &ctx->a,
3071                         .type           = WREPL_TYPE_MHOMED,
3072                         .state          = WREPL_STATE_ACTIVE,
3073                         .node           = WREPL_NODE_B,
3074                         .is_static      = False,
3075                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3076                         .ips            = addresses_A_1,
3077                         .apply_expected = True
3078                 },
3079                 .r2     = {
3080                         .owner          = &ctx->b,
3081                         .type           = WREPL_TYPE_GROUP,
3082                         .state          = WREPL_STATE_ACTIVE,
3083                         .node           = WREPL_NODE_B,
3084                         .is_static      = False,
3085                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3086                         .ips            = addresses_B_1,
3087                         .apply_expected = True
3088                 }
3089         },
3090
3091         /* 
3092          * mhomed,active vs. group,tombstone
3093          * => should NOT be replaced
3094          */
3095         {
3096                 .line   = __location__,
3097                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3098                 .r1     = {
3099                         .owner          = &ctx->b,
3100                         .type           = WREPL_TYPE_MHOMED,
3101                         .state          = WREPL_STATE_ACTIVE,
3102                         .node           = WREPL_NODE_B,
3103                         .is_static      = False,
3104                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3105                         .ips            = addresses_B_1,
3106                         .apply_expected = True
3107                 },
3108                 .r2     = {
3109                         .owner          = &ctx->a,
3110                         .type           = WREPL_TYPE_GROUP,
3111                         .state          = WREPL_STATE_TOMBSTONE,
3112                         .node           = WREPL_NODE_B,
3113                         .is_static      = False,
3114                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3115                         .ips            = addresses_B_1,
3116                         .apply_expected = False
3117                 }
3118         },
3119
3120         /* 
3121          * mhomed,released vs. group,active
3122          * => should be replaced
3123          */
3124         {
3125                 .line   = __location__,
3126                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3127                 .r1     = {
3128                         .owner          = &ctx->b,
3129                         .type           = WREPL_TYPE_MHOMED,
3130                         .state          = WREPL_STATE_RELEASED,
3131                         .node           = WREPL_NODE_B,
3132                         .is_static      = False,
3133                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3134                         .ips            = addresses_B_1,
3135                         .apply_expected = False
3136                 },
3137                 .r2     = {
3138                         .owner          = &ctx->a,
3139                         .type           = WREPL_TYPE_GROUP,
3140                         .state          = WREPL_STATE_ACTIVE,
3141                         .node           = WREPL_NODE_B,
3142                         .is_static      = False,
3143                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3144                         .ips            = addresses_A_1,
3145                         .apply_expected = True
3146                 }
3147         },
3148
3149         /* 
3150          * mhomed,released vs. group,tombstone
3151          * => should be replaced
3152          */
3153         {
3154                 .line   = __location__,
3155                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3156                 .r1     = {
3157                         .owner          = &ctx->a,
3158                         .type           = WREPL_TYPE_MHOMED,
3159                         .state          = WREPL_STATE_RELEASED,
3160                         .node           = WREPL_NODE_B,
3161                         .is_static      = False,
3162                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3163                         .ips            = addresses_A_1,
3164                         .apply_expected = False
3165                 },
3166                 .r2     = {
3167                         .owner          = &ctx->b,
3168                         .type           = WREPL_TYPE_GROUP,
3169                         .state          = WREPL_STATE_TOMBSTONE,
3170                         .node           = WREPL_NODE_B,
3171                         .is_static      = False,
3172                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3173                         .ips            = addresses_B_1,
3174                         .apply_expected = True
3175                 }
3176         },
3177
3178         /* 
3179          * mhomed,tombstone vs. group,active
3180          * => should be replaced
3181          */
3182         {
3183                 .line   = __location__,
3184                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3185                 .r1     = {
3186                         .owner          = &ctx->b,
3187                         .type           = WREPL_TYPE_MHOMED,
3188                         .state          = WREPL_STATE_TOMBSTONE,
3189                         .node           = WREPL_NODE_B,
3190                         .is_static      = False,
3191                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3192                         .ips            = addresses_B_1,
3193                         .apply_expected = True
3194                 },
3195                 .r2     = {
3196                         .owner          = &ctx->a,
3197                         .type           = WREPL_TYPE_GROUP,
3198                         .state          = WREPL_STATE_ACTIVE,
3199                         .node           = WREPL_NODE_B,
3200                         .is_static      = False,
3201                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3202                         .ips            = addresses_A_1,
3203                         .apply_expected = True
3204                 }
3205         },
3206
3207         /* 
3208          * mhomed,tombstone vs. group,tombstone
3209          * => should be replaced
3210          */
3211         {
3212                 .line   = __location__,
3213                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3214                 .r1     = {
3215                         .owner          = &ctx->a,
3216                         .type           = WREPL_TYPE_MHOMED,
3217                         .state          = WREPL_STATE_TOMBSTONE,
3218                         .node           = WREPL_NODE_B,
3219                         .is_static      = False,
3220                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3221                         .ips            = addresses_A_1,
3222                         .apply_expected = True
3223                 },
3224                 .r2     = {
3225                         .owner          = &ctx->b,
3226                         .type           = WREPL_TYPE_GROUP,
3227                         .state          = WREPL_STATE_TOMBSTONE,
3228                         .node           = WREPL_NODE_B,
3229                         .is_static      = False,
3230                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3231                         .ips            = addresses_B_1,
3232                         .apply_expected = True
3233                 }
3234         },
3235
3236 /*
3237  * multi homed vs. special group section,
3238  */
3239         /* 
3240          * mhomed,active vs. sgroup,active
3241          * => should NOT be replaced
3242          */
3243         {
3244                 .line   = __location__,
3245                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3246                 .r1     = {
3247                         .owner          = &ctx->a,
3248                         .type           = WREPL_TYPE_MHOMED,
3249                         .state          = WREPL_STATE_ACTIVE,
3250                         .node           = WREPL_NODE_B,
3251                         .is_static      = False,
3252                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3253                         .ips            = addresses_A_1,
3254                         .apply_expected = True
3255                 },
3256                 .r2     = {
3257                         .owner          = &ctx->b,
3258                         .type           = WREPL_TYPE_SGROUP,
3259                         .state          = WREPL_STATE_ACTIVE,
3260                         .node           = WREPL_NODE_B,
3261                         .is_static      = False,
3262                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3263                         .ips            = addresses_A_1,
3264                         .apply_expected = False
3265                 }
3266         },
3267
3268         /* 
3269          * mhomed,active vs. sgroup,tombstone
3270          * => should NOT be replaced
3271          */
3272         {
3273                 .line   = __location__,
3274                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3275                 .r1     = {
3276                         .owner          = &ctx->a,
3277                         .type           = WREPL_TYPE_MHOMED,
3278                         .state          = WREPL_STATE_ACTIVE,
3279                         .node           = WREPL_NODE_B,
3280                         .is_static      = False,
3281                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3282                         .ips            = addresses_A_1,
3283                         .apply_expected = True
3284                 },
3285                 .r2     = {
3286                         .owner          = &ctx->b,
3287                         .type           = WREPL_TYPE_SGROUP,
3288                         .state          = WREPL_STATE_TOMBSTONE,
3289                         .node           = WREPL_NODE_B,
3290                         .is_static      = False,
3291                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3292                         .ips            = addresses_A_1,
3293                         .apply_expected = False
3294                 }
3295         },
3296
3297         /* 
3298          * mhomed,released vs. sgroup,active
3299          * => should be replaced
3300          */
3301         {
3302                 .line   = __location__,
3303                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3304                 .r1     = {
3305                         .owner          = &ctx->a,
3306                         .type           = WREPL_TYPE_MHOMED,
3307                         .state          = WREPL_STATE_RELEASED,
3308                         .node           = WREPL_NODE_B,
3309                         .is_static      = False,
3310                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3311                         .ips            = addresses_A_1,
3312                         .apply_expected = False
3313                 },
3314                 .r2     = {
3315                         .owner          = &ctx->b,
3316                         .type           = WREPL_TYPE_SGROUP,
3317                         .state          = WREPL_STATE_ACTIVE,
3318                         .node           = WREPL_NODE_B,
3319                         .is_static      = False,
3320                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3321                         .ips            = addresses_B_1,
3322                         .apply_expected = True
3323                 }
3324         },
3325
3326         /* 
3327          * mhomed,released vs. sgroup,tombstone
3328          * => should be replaced
3329          */
3330         {
3331                 .line   = __location__,
3332                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3333                 .r1     = {
3334                         .owner          = &ctx->b,
3335                         .type           = WREPL_TYPE_MHOMED,
3336                         .state          = WREPL_STATE_RELEASED,
3337                         .node           = WREPL_NODE_B,
3338                         .is_static      = False,
3339                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3340                         .ips            = addresses_B_1,
3341                         .apply_expected = False
3342                 },
3343                 .r2     = {
3344                         .owner          = &ctx->a,
3345                         .type           = WREPL_TYPE_SGROUP,
3346                         .state          = WREPL_STATE_TOMBSTONE,
3347                         .node           = WREPL_NODE_B,
3348                         .is_static      = False,
3349                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3350                         .ips            = addresses_A_1,
3351                         .apply_expected = True
3352                 }
3353         },
3354
3355         /* 
3356          * mhomed,tombstone vs. sgroup,active
3357          * => should be replaced
3358          */
3359         {
3360                 .line   = __location__,
3361                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3362                 .r1     = {
3363                         .owner          = &ctx->a,
3364                         .type           = WREPL_TYPE_MHOMED,
3365                         .state          = WREPL_STATE_TOMBSTONE,
3366                         .node           = WREPL_NODE_B,
3367                         .is_static      = False,
3368                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3369                         .ips            = addresses_A_1,
3370                         .apply_expected = True
3371                 },
3372                 .r2     = {
3373                         .owner          = &ctx->b,
3374                         .type           = WREPL_TYPE_SGROUP,
3375                         .state          = WREPL_STATE_ACTIVE,
3376                         .node           = WREPL_NODE_B,
3377                         .is_static      = False,
3378                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3379                         .ips            = addresses_B_1,
3380                         .apply_expected = True
3381                 }
3382         },
3383
3384         /* 
3385          * mhomed,tombstone vs. sgroup,tombstone
3386          * => should be replaced
3387          */
3388         {
3389                 .line   = __location__,
3390                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3391                 .r1     = {
3392                         .owner          = &ctx->b,
3393                         .type           = WREPL_TYPE_MHOMED,
3394                         .state          = WREPL_STATE_TOMBSTONE,
3395                         .node           = WREPL_NODE_B,
3396                         .is_static      = False,
3397                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3398                         .ips            = addresses_B_1,
3399                         .apply_expected = True
3400                 },
3401                 .r2     = {
3402                         .owner          = &ctx->a,
3403                         .type           = WREPL_TYPE_SGROUP,
3404                         .state          = WREPL_STATE_TOMBSTONE,
3405                         .node           = WREPL_NODE_B,
3406                         .is_static      = False,
3407                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3408                         .ips            = addresses_A_1,
3409                         .apply_expected = True
3410                 }
3411         },
3412
3413 /*
3414  * multi homed vs. mlti homed section,
3415  */
3416         /* 
3417          * mhomed,active vs. mhomed,active
3418          * => should be replaced
3419          */
3420         {
3421                 .line   = __location__,
3422                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3423                 .r1     = {
3424                         .owner          = &ctx->a,
3425                         .type           = WREPL_TYPE_MHOMED,
3426                         .state          = WREPL_STATE_ACTIVE,
3427                         .node           = WREPL_NODE_B,
3428                         .is_static      = False,
3429                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
3430                         .ips            = addresses_A_3_4,
3431                         .apply_expected = True
3432                 },
3433                 .r2     = {
3434                         .owner          = &ctx->b,
3435                         .type           = WREPL_TYPE_MHOMED,
3436                         .state          = WREPL_STATE_ACTIVE,
3437                         .node           = WREPL_NODE_B,
3438                         .is_static      = False,
3439                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
3440                         .ips            = addresses_B_3_4,
3441                         .apply_expected = True
3442                 }
3443         },
3444
3445         /* 
3446          * mhomed,active vs. mhomed,tombstone
3447          * => should NOT be replaced
3448          */
3449         {
3450                 .line   = __location__,
3451                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3452                 .r1     = {
3453                         .owner          = &ctx->b,
3454                         .type           = WREPL_TYPE_MHOMED,
3455                         .state          = WREPL_STATE_ACTIVE,
3456                         .node           = WREPL_NODE_B,
3457                         .is_static      = False,
3458                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
3459                         .ips            = addresses_B_3_4,
3460                         .apply_expected = True
3461                 },
3462                 .r2     = {
3463                         .owner          = &ctx->a,
3464                         .type           = WREPL_TYPE_MHOMED,
3465                         .state          = WREPL_STATE_TOMBSTONE,
3466                         .node           = WREPL_NODE_B,
3467                         .is_static      = False,
3468                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
3469                         .ips            = addresses_B_3_4,
3470                         .apply_expected = False
3471                 }
3472         },
3473
3474         /* 
3475          * mhomed,released vs. mhomed,active
3476          * => should be replaced
3477          */
3478         {
3479                 .line   = __location__,
3480                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3481                 .r1     = {
3482                         .owner          = &ctx->b,
3483                         .type           = WREPL_TYPE_MHOMED,
3484                         .state          = WREPL_STATE_RELEASED,
3485                         .node           = WREPL_NODE_B,
3486                         .is_static      = False,
3487                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
3488                         .ips            = addresses_B_3_4,
3489                         .apply_expected = False
3490                 },
3491                 .r2     = {
3492                         .owner          = &ctx->a,
3493                         .type           = WREPL_TYPE_MHOMED,
3494                         .state          = WREPL_STATE_ACTIVE,
3495                         .node           = WREPL_NODE_B,
3496                         .is_static      = False,
3497                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
3498                         .ips            = addresses_A_3_4,
3499                         .apply_expected = True
3500                 }
3501         },
3502
3503         /* 
3504          * mhomed,released vs. mhomed,tombstone
3505          * => should be replaced
3506          */
3507         {
3508                 .line   = __location__,
3509                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3510                 .r1     = {
3511                         .owner          = &ctx->a,
3512                         .type           = WREPL_TYPE_MHOMED,
3513                         .state          = WREPL_STATE_RELEASED,
3514                         .node           = WREPL_NODE_B,
3515                         .is_static      = False,
3516                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
3517                         .ips            = addresses_A_3_4,
3518                         .apply_expected = False
3519                 },
3520                 .r2     = {
3521                         .owner          = &ctx->b,
3522                         .type           = WREPL_TYPE_MHOMED,
3523                         .state          = WREPL_STATE_TOMBSTONE,
3524                         .node           = WREPL_NODE_B,
3525                         .is_static      = False,
3526                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
3527                         .ips            = addresses_B_3_4,
3528                         .apply_expected = True
3529                 }
3530         },
3531
3532         /* 
3533          * mhomed,tombstone vs. mhomed,active
3534          * => should be replaced
3535          */
3536         {
3537                 .line   = __location__,
3538                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3539                 .r1     = {
3540                         .owner          = &ctx->b,
3541                         .type           = WREPL_TYPE_MHOMED,
3542                         .state          = WREPL_STATE_TOMBSTONE,
3543                         .node           = WREPL_NODE_B,
3544                         .is_static      = False,
3545                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
3546                         .ips            = addresses_B_3_4,
3547                         .apply_expected = True
3548                 },
3549                 .r2     = {
3550                         .owner          = &ctx->a,
3551                         .type           = WREPL_TYPE_MHOMED,
3552                         .state          = WREPL_STATE_ACTIVE,
3553                         .node           = WREPL_NODE_B,
3554                         .is_static      = False,
3555                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
3556                         .ips            = addresses_A_3_4,
3557                         .apply_expected = True
3558                 }
3559         },
3560
3561         /* 
3562          * mhomed,tombstone vs. mhomed,tombstone
3563          * => should be replaced
3564          */
3565         {
3566                 .line   = __location__,
3567                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3568                 .r1     = {
3569                         .owner          = &ctx->a,
3570                         .type           = WREPL_TYPE_MHOMED,
3571                         .state          = WREPL_STATE_TOMBSTONE,
3572                         .node           = WREPL_NODE_B,
3573                         .is_static      = False,
3574                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
3575                         .ips            = addresses_A_3_4,
3576                         .apply_expected = True
3577                 },
3578                 .r2     = {
3579                         .owner          = &ctx->b,
3580                         .type           = WREPL_TYPE_MHOMED,
3581                         .state          = WREPL_STATE_TOMBSTONE,
3582                         .node           = WREPL_NODE_B,
3583                         .is_static      = False,
3584                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
3585                         .ips            = addresses_B_3_4,
3586                         .apply_expected = True
3587                 }
3588         },
3589
3590 #if 0
3591 /*
3592  * special group vs special group section,
3593  */
3594         /* 
3595          * sgroup,active vs. sgroup,active
3596          * => should be merged
3597          */
3598         {
3599                 .line   = __location__,
3600                 .name   = _NBT_NAME("_DIFF_OWNER_SG", 0x00, NULL),
3601                 .extra  = True,
3602                 .r1     = {
3603                         .owner          = &ctx->a,
3604                         .type           = WREPL_TYPE_SGROUP,
3605                         .state          = WREPL_STATE_ACTIVE,
3606                         .node           = WREPL_NODE_B,
3607                         .is_static      = False,
3608                         .num_ips        = ARRAY_SIZE(addresses_A_3_4),
3609                         .ips            = addresses_A_3_4,
3610                         .apply_expected = True,
3611                 },
3612                 .r2     = {
3613                         .owner          = &ctx->b,
3614                         .type           = WREPL_TYPE_SGROUP,
3615                         .state          = WREPL_STATE_ACTIVE,
3616                         .node           = WREPL_NODE_B,
3617                         .is_static      = False,
3618                         .num_ips        = ARRAY_SIZE(addresses_B_3_4),
3619                         .ips            = addresses_B_3_4,
3620                         .apply_expected = False,
3621                         .merge_expected = True
3622                 }
3623         },
3624         {
3625                 .line   = __location__,
3626                 .name   = _NBT_NAME("_DIFF_OWNER_SG", 0x00, NULL),
3627                 .cleanup= True,
3628                 .r1     = {
3629                         .owner          = &ctx->a,
3630                         .type           = WREPL_TYPE_SGROUP,
3631                         .state          = WREPL_STATE_ACTIVE,
3632                         .node           = WREPL_NODE_B,
3633                         .is_static      = False,
3634                         .num_ips        = 0,
3635                         .ips            = NULL,
3636                         .apply_expected = False
3637                 },
3638                 .r2     = {
3639                         .owner          = &ctx->b,
3640                         .type           = WREPL_TYPE_SGROUP,
3641                         .state          = WREPL_STATE_ACTIVE,
3642                         .node           = WREPL_NODE_B,
3643                         .is_static      = False,
3644                         .num_ips        = 0,
3645                         .ips            = NULL,
3646                         .apply_expected = False,
3647                         .merge_expected = False
3648                 }
3649         },
3650         {
3651                 .line   = __location__,
3652                 .name   = _NBT_NAME("_DIFF_OWNER_SG", 0x00, NULL),
3653                 .cleanup= True,
3654                 .r1     = {
3655                         .owner          = &ctx->a,
3656                         .type           = WREPL_TYPE_SGROUP,
3657                         .state          = WREPL_STATE_ACTIVE,
3658                         .node           = WREPL_NODE_B,
3659                         .is_static      = False,
3660                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3661                         .ips            = addresses_A_1,
3662                         .apply_expected = True
3663                 },
3664                 .r2     = {
3665                         .owner          = &ctx->a,
3666                         .type           = WREPL_TYPE_UNIQUE,
3667                         .state          = WREPL_STATE_TOMBSTONE,
3668                         .node           = WREPL_NODE_B,
3669                         .is_static      = False,
3670                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3671                         .ips            = addresses_A_1,
3672                         .apply_expected = True
3673                 }
3674         },
3675 #endif
3676         /* 
3677          * This should be the last record in this array,
3678          * we need to make sure the we leave a tombstoned unique entry
3679          * owned by OWNER_A
3680          */
3681         {
3682                 .line   = __location__,
3683                 .name   = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3684                 .cleanup= True,
3685                 .r1     = {
3686                         .owner          = &ctx->b,
3687                         .type           = WREPL_TYPE_UNIQUE,
3688                         .state          = WREPL_STATE_TOMBSTONE,
3689                         .node           = WREPL_NODE_B,
3690                         .is_static      = False,
3691                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3692                         .ips            = addresses_A_1,
3693                         .apply_expected = True
3694                 },
3695                 .r2     = {
3696                         .owner          = &ctx->a,
3697                         .type           = WREPL_TYPE_UNIQUE,
3698                         .state          = WREPL_STATE_TOMBSTONE,
3699                         .node           = WREPL_NODE_B,
3700                         .is_static      = False,
3701                         .num_ips        = ARRAY_SIZE(addresses_A_1),
3702                         .ips            = addresses_A_1,
3703                         .apply_expected = True
3704                 }
3705         }}; /* do not add entries here, this should be the last record! */
3706
3707         if (!ctx) return False;
3708
3709         wins_name_r1    = &wins_name1;
3710         wins_name_r2    = &wins_name2;
3711
3712         printf("Test Replica Conflicts with different owners\n");
3713
3714         for(i=0; ret && i < ARRAY_SIZE(records); i++) {
3715         
3716                 if (!records[i].extra && !records[i].cleanup) {
3717                         /* we should test the worst cases */
3718                         if (records[i].r2.apply_expected && records[i].r1.ips==records[i].r2.ips) {
3719                                 printf("(%s) Programmer error, invalid record[%u]: %s\n",
3720                                         __location__, i, records[i].line);
3721                                 return False;
3722                         } else if (!records[i].r2.apply_expected && records[i].r1.ips!=records[i].r2.ips) {
3723                                 printf("(%s) Programmer error, invalid record[%u]: %s\n",
3724                                         __location__, i, records[i].line);
3725                                 return False;
3726                         }
3727                 }
3728
3729                 if (!records[i].cleanup) {
3730                         const char *expected;
3731                         const char *ips;
3732
3733                         if (records[i].r2.merge_expected) {
3734                                 expected = "MERGE";
3735                         } else if (records[i].r2.apply_expected) {
3736                                 expected = "REPLACE";
3737                         } else {
3738                                 expected = "NOT REPLACE";
3739                         }
3740
3741                         if (!records[i].r1.ips && !records[i].r2.ips) {
3742                                 ips = "no";
3743                         } else if (records[i].r1.ips==records[i].r2.ips) {
3744                                 ips = "same";
3745                         } else {
3746                                 ips = "different";
3747                         }
3748
3749                         printf("%s,%s%s vs. %s,%s%s with %s ip(s) => %s\n",
3750                                 wrepl_name_type_string(records[i].r1.type),
3751                                 wrepl_name_state_string(records[i].r1.state),
3752                                 (records[i].r1.is_static?",static":""),
3753                                 wrepl_name_type_string(records[i].r2.type),
3754                                 wrepl_name_state_string(records[i].r2.state),
3755                                 (records[i].r2.is_static?",static":""),
3756                                 ips, expected);
3757                 }
3758
3759                 /*
3760                  * Setup R1
3761                  */
3762                 wins_name_r1->name      = &records[i].name;
3763                 wins_name_r1->flags     = WREPL_NAME_FLAGS(records[i].r1.type,
3764                                                            records[i].r1.state,
3765                                                            records[i].r1.node,
3766                                                            records[i].r1.is_static);
3767                 wins_name_r1->id        = ++records[i].r1.owner->max_version;
3768                 if (wins_name_r1->flags & 2) {
3769                         wins_name_r1->addresses.addresses.num_ips = records[i].r1.num_ips;
3770                         wins_name_r1->addresses.addresses.ips     = discard_const(records[i].r1.ips);
3771                 } else {
3772                         wins_name_r1->addresses.ip = records[i].r1.ips[0].ip;
3773                 }
3774                 wins_name_r1->unknown   = "255.255.255.255";
3775
3776                 /* now apply R1 */
3777                 ret &= test_wrepl_update_one(ctx, records[i].r1.owner, wins_name_r1);
3778                 ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
3779                                              wins_name_r1, records[i].r1.apply_expected);
3780
3781                 /*
3782                  * Setup R2
3783                  */
3784                 wins_name_r2->name      = &records[i].name;
3785                 wins_name_r2->flags     = WREPL_NAME_FLAGS(records[i].r2.type,
3786                                                            records[i].r2.state,
3787                                                            records[i].r2.node,
3788                                                            records[i].r2.is_static);
3789                 wins_name_r2->id        = ++records[i].r2.owner->max_version;
3790                 if (wins_name_r2->flags & 2) {
3791                         wins_name_r2->addresses.addresses.num_ips = records[i].r2.num_ips;
3792                         wins_name_r2->addresses.addresses.ips     = discard_const(records[i].r2.ips);
3793                 } else {
3794                         wins_name_r2->addresses.ip = records[i].r2.ips[0].ip;
3795                 }
3796                 wins_name_r2->unknown   = "255.255.255.255";
3797
3798                 /* now apply R2 */
3799                 ret &= test_wrepl_update_one(ctx, records[i].r2.owner, wins_name_r2);
3800                 if (records[i].r1.state == WREPL_STATE_RELEASED) {
3801                         ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
3802                                                      wins_name_r1, False);
3803                 } else if (records[i].r2.merge_expected) {
3804                         ret &= test_wrepl_is_merged(ctx, wins_name_r1, wins_name_r2);           
3805                 } else if (records[i].r1.owner != records[i].r2.owner) {
3806                         BOOL _expected;
3807                         _expected = (records[i].r1.apply_expected && !records[i].r2.apply_expected);
3808                         ret &= test_wrepl_is_applied(ctx, records[i].r1.owner,
3809                                                      wins_name_r1, _expected);
3810                 }
3811                 if (records[i].r2.state == WREPL_STATE_RELEASED) {
3812                         ret &= test_wrepl_is_applied(ctx, records[i].r2.owner,
3813                                                      wins_name_r2, False);
3814                 } else if (!records[i].r2.merge_expected) {
3815                         ret &= test_wrepl_is_applied(ctx, records[i].r2.owner,
3816                                                      wins_name_r2, records[i].r2.apply_expected);
3817                 }
3818
3819                 /* the first one is a cleanup run */
3820                 if (!ret && i == 0) ret = True;
3821
3822                 if (!ret) {
3823                         printf("conflict handled wrong or record[%u]: %s\n", i, records[i].line);
3824                         return ret;
3825                 }
3826         }
3827
3828         return ret;
3829 }
3830
3831 static BOOL test_conflict_owned_released_vs_replica(struct test_wrepl_conflict_conn *ctx)
3832 {
3833         BOOL ret = True;
3834         NTSTATUS status;
3835         struct wrepl_wins_name wins_name_;
3836         struct wrepl_wins_name *wins_name = &wins_name_;
3837         struct nbt_name_register name_register_;
3838         struct nbt_name_register *name_register = &name_register_;
3839         struct nbt_name_release release_;
3840         struct nbt_name_release *release = &release_;
3841         uint32_t i;
3842         struct {
3843                 const char *line; /* just better debugging */
3844                 struct nbt_name name;
3845                 struct {
3846                         uint32_t nb_flags;
3847                         BOOL mhomed;
3848                         uint32_t num_ips;
3849                         const struct wrepl_ip *ips;
3850                         BOOL apply_expected;
3851                 } wins;
3852                 struct {
3853                         enum wrepl_name_type type;
3854                         enum wrepl_name_state state;
3855                         enum wrepl_name_node node;
3856                         BOOL is_static;
3857                         uint32_t num_ips;
3858                         const struct wrepl_ip *ips;
3859                         BOOL apply_expected;
3860                 } replica;
3861         } records[] = {
3862 /* 
3863  * unique vs. unique section
3864  */
3865         /*
3866          * unique,released vs. unique,active with same ip(s)
3867          */
3868         {
3869                 .line   = __location__,
3870                 .name   = _NBT_NAME("_UR_UA_SI", 0x00, NULL),
3871                 .wins   = {
3872                         .nb_flags       = 0,
3873                         .mhomed         = False,
3874                         .num_ips        = ctx->addresses_1_num,
3875                         .ips            = ctx->addresses_1,
3876                         .apply_expected = True
3877                 },
3878                 .replica= {
3879                         .type           = WREPL_TYPE_UNIQUE,
3880                         .state          = WREPL_STATE_ACTIVE,
3881                         .node           = WREPL_NODE_B,
3882                         .is_static      = False,
3883                         .num_ips        = ctx->addresses_1_num,
3884                         .ips            = ctx->addresses_1,
3885                         .apply_expected = True
3886                 },
3887         },
3888         /*
3889          * unique,released vs. unique,active with different ip(s)
3890          */
3891         {
3892                 .line   = __location__,
3893                 .name   = _NBT_NAME("_UR_UA_DI", 0x00, NULL),
3894                 .wins   = {
3895                         .nb_flags       = 0,
3896                         .mhomed         = False,
3897                         .num_ips        = ctx->addresses_1_num,
3898                         .ips            = ctx->addresses_1,
3899                         .apply_expected = True
3900                 },
3901                 .replica= {
3902                         .type           = WREPL_TYPE_UNIQUE,
3903                         .state          = WREPL_STATE_ACTIVE,
3904                         .node           = WREPL_NODE_B,
3905                         .is_static      = False,
3906                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3907                         .ips            = addresses_B_1,
3908                         .apply_expected = True
3909                 },
3910         },
3911         /*
3912          * unique,released vs. unique,tombstone with same ip(s)
3913          */
3914         {
3915                 .line   = __location__,
3916                 .name   = _NBT_NAME("_UR_UT_SI", 0x00, NULL),
3917                 .wins   = {
3918                         .nb_flags       = 0,
3919                         .mhomed         = False,
3920                         .num_ips        = ctx->addresses_1_num,
3921                         .ips            = ctx->addresses_1,
3922                         .apply_expected = True
3923                 },
3924                 .replica= {
3925                         .type           = WREPL_TYPE_UNIQUE,
3926                         .state          = WREPL_STATE_TOMBSTONE,
3927                         .node           = WREPL_NODE_B,
3928                         .is_static      = False,
3929                         .num_ips        = ctx->addresses_1_num,
3930                         .ips            = ctx->addresses_1,
3931                         .apply_expected = True
3932                 },
3933         },
3934         /*
3935          * unique,released vs. unique,tombstone with different ip(s)
3936          */
3937         {
3938                 .line   = __location__,
3939                 .name   = _NBT_NAME("_UR_UT_DI", 0x00, NULL),
3940                 .wins   = {
3941                         .nb_flags       = 0,
3942                         .mhomed         = False,
3943                         .num_ips        = ctx->addresses_1_num,
3944                         .ips            = ctx->addresses_1,
3945                         .apply_expected = True
3946                 },
3947                 .replica= {
3948                         .type           = WREPL_TYPE_UNIQUE,
3949                         .state          = WREPL_STATE_TOMBSTONE,
3950                         .node           = WREPL_NODE_B,
3951                         .is_static      = False,
3952                         .num_ips        = ARRAY_SIZE(addresses_B_1),
3953                         .ips            = addresses_B_1,
3954                         .apply_expected = True
3955                 },
3956         },
3957 /* 
3958  * unique vs. group section
3959  */
3960         /*
3961          * unique,released vs. group,active with same ip(s)
3962          */
3963         {
3964                 .line   = __location__,
3965                 .name   = _NBT_NAME("_UR_GA_SI", 0x00, NULL),
3966                 .wins   = {
3967                         .nb_flags       = 0,
3968                         .mhomed         = False,
3969                         .num_ips        = ctx->addresses_1_num,
3970                         .ips            = ctx->addresses_1,
3971                         .apply_expected = True
3972                 },
3973                 .replica= {
3974                         .type           = WREPL_TYPE_GROUP,
3975                         .state          = WREPL_STATE_ACTIVE,
3976                         .node           = WREPL_NODE_B,
3977                         .is_static      = False,
3978                         .num_ips        = ctx->addresses_1_num,
3979                         .ips            = ctx->addresses_1,
3980                         .apply_expected = True
3981                 },
3982         },
3983         /*
3984          * unique,released vs. group,active with different ip(s)
3985          */
3986         {
3987                 .line   = __location__,
3988                 .name   = _NBT_NAME("_UR_GA_DI", 0x00, NULL),
3989                 .wins   = {
3990                         .nb_flags       = 0,
3991                         .mhomed         = False,
3992                         .num_ips        = ctx->addresses_1_num,
3993                         .ips            = ctx->addresses_1,
3994                         .apply_expected = True
3995                 },
3996                 .replica= {
3997                         .type           = WREPL_TYPE_GROUP,
3998                         .state          = WREPL_STATE_ACTIVE,
3999                         .node           = WREPL_NODE_B,
4000                         .is_static      = False,
4001                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4002                         .ips            = addresses_B_1,
4003                         .apply_expected = True
4004                 },
4005         },
4006         /*
4007          * unique,released vs. group,tombstone with same ip(s)
4008          */
4009         {
4010                 .line   = __location__,
4011                 .name   = _NBT_NAME("_UR_GT_SI", 0x00, NULL),
4012                 .wins   = {
4013                         .nb_flags       = 0,
4014                         .mhomed         = False,
4015                         .num_ips        = ctx->addresses_1_num,
4016                         .ips            = ctx->addresses_1,
4017                         .apply_expected = True
4018                 },
4019                 .replica= {
4020                         .type           = WREPL_TYPE_GROUP,
4021                         .state          = WREPL_STATE_TOMBSTONE,
4022                         .node           = WREPL_NODE_B,
4023                         .is_static      = False,
4024                         .num_ips        = ctx->addresses_1_num,
4025                         .ips            = ctx->addresses_1,
4026                         .apply_expected = True
4027                 },
4028         },
4029         /*
4030          * unique,released vs. group,tombstone with different ip(s)
4031          */
4032         {
4033                 .line   = __location__,
4034                 .name   = _NBT_NAME("_UR_GT_DI", 0x00, NULL),
4035                 .wins   = {
4036                         .nb_flags       = 0,
4037                         .mhomed         = False,
4038                         .num_ips        = ctx->addresses_1_num,
4039                         .ips            = ctx->addresses_1,
4040                         .apply_expected = True
4041                 },
4042                 .replica= {
4043                         .type           = WREPL_TYPE_GROUP,
4044                         .state          = WREPL_STATE_TOMBSTONE,
4045                         .node           = WREPL_NODE_B,
4046                         .is_static      = False,
4047                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4048                         .ips            = addresses_B_1,
4049                         .apply_expected = True
4050                 },
4051         },
4052 /* 
4053  * unique vs. special group section
4054  */
4055         /*
4056          * unique,released vs. sgroup,active with same ip(s)
4057          */
4058         {
4059                 .line   = __location__,
4060                 .name   = _NBT_NAME("_UR_SA_SI", 0x00, NULL),
4061                 .wins   = {
4062                         .nb_flags       = 0,
4063                         .mhomed         = False,
4064                         .num_ips        = ctx->addresses_1_num,
4065                         .ips            = ctx->addresses_1,
4066                         .apply_expected = True
4067                 },
4068                 .replica= {
4069                         .type           = WREPL_TYPE_SGROUP,
4070                         .state          = WREPL_STATE_ACTIVE,
4071                         .node           = WREPL_NODE_B,
4072                         .is_static      = False,
4073                         .num_ips        = ctx->addresses_1_num,
4074                         .ips            = ctx->addresses_1,
4075                         .apply_expected = True
4076                 },
4077         },
4078         /*
4079          * unique,released vs. sgroup,active with different ip(s)
4080          */
4081         {
4082                 .line   = __location__,
4083                 .name   = _NBT_NAME("_UR_SA_DI", 0x00, NULL),
4084                 .wins   = {
4085                         .nb_flags       = 0,
4086                         .mhomed         = False,
4087                         .num_ips        = ctx->addresses_1_num,
4088                         .ips            = ctx->addresses_1,
4089                         .apply_expected = True
4090                 },
4091                 .replica= {
4092                         .type           = WREPL_TYPE_SGROUP,
4093                         .state          = WREPL_STATE_ACTIVE,
4094                         .node           = WREPL_NODE_B,
4095                         .is_static      = False,
4096                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4097                         .ips            = addresses_B_1,
4098                         .apply_expected = True
4099                 },
4100         },
4101         /*
4102          * unique,released vs. sgroup,tombstone with same ip(s)
4103          */
4104         {
4105                 .line   = __location__,
4106                 .name   = _NBT_NAME("_UR_ST_SI", 0x00, NULL),
4107                 .wins   = {
4108                         .nb_flags       = 0,
4109                         .mhomed         = False,
4110                         .num_ips        = ctx->addresses_1_num,
4111                         .ips            = ctx->addresses_1,
4112                         .apply_expected = True
4113                 },
4114                 .replica= {
4115                         .type           = WREPL_TYPE_SGROUP,
4116                         .state          = WREPL_STATE_TOMBSTONE,
4117                         .node           = WREPL_NODE_B,
4118                         .is_static      = False,
4119                         .num_ips        = ctx->addresses_1_num,
4120                         .ips            = ctx->addresses_1,
4121                         .apply_expected = True
4122                 },
4123         },
4124         /*
4125          * unique,released vs. sgroup,tombstone with different ip(s)
4126          */
4127         {
4128                 .line   = __location__,
4129                 .name   = _NBT_NAME("_UR_ST_DI", 0x00, NULL),
4130                 .wins   = {
4131                         .nb_flags       = 0,
4132                         .mhomed         = False,
4133                         .num_ips        = ctx->addresses_1_num,
4134                         .ips            = ctx->addresses_1,
4135                         .apply_expected = True
4136                 },
4137                 .replica= {
4138                         .type           = WREPL_TYPE_SGROUP,
4139                         .state          = WREPL_STATE_TOMBSTONE,
4140                         .node           = WREPL_NODE_B,
4141                         .is_static      = False,
4142                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4143                         .ips            = addresses_B_1,
4144                         .apply_expected = True
4145                 },
4146         },
4147 /* 
4148  * unique vs. multi homed section
4149  */
4150         /*
4151          * unique,released vs. mhomed,active with same ip(s)
4152          */
4153         {
4154                 .line   = __location__,
4155                 .name   = _NBT_NAME("_UR_MA_SI", 0x00, NULL),
4156                 .wins   = {
4157                         .nb_flags       = 0,
4158                         .mhomed         = False,
4159                         .num_ips        = ctx->addresses_1_num,
4160                         .ips            = ctx->addresses_1,
4161                         .apply_expected = True
4162                 },
4163                 .replica= {
4164                         .type           = WREPL_TYPE_MHOMED,
4165                         .state          = WREPL_STATE_ACTIVE,
4166                         .node           = WREPL_NODE_B,
4167                         .is_static      = False,
4168                         .num_ips        = ctx->addresses_1_num,
4169                         .ips            = ctx->addresses_1,
4170                         .apply_expected = True
4171                 },
4172         },
4173         /*
4174          * unique,released vs. mhomed,active with different ip(s)
4175          */
4176         {
4177                 .line   = __location__,
4178                 .name   = _NBT_NAME("_UR_MA_DI", 0x00, NULL),
4179                 .wins   = {
4180                         .nb_flags       = 0,
4181                         .mhomed         = False,
4182                         .num_ips        = ctx->addresses_1_num,
4183                         .ips            = ctx->addresses_1,
4184                         .apply_expected = True
4185                 },
4186                 .replica= {
4187                         .type           = WREPL_TYPE_MHOMED,
4188                         .state          = WREPL_STATE_ACTIVE,
4189                         .node           = WREPL_NODE_B,
4190                         .is_static      = False,
4191                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4192                         .ips            = addresses_B_1,
4193                         .apply_expected = True
4194                 },
4195         },
4196         /*
4197          * unique,released vs. mhomed,tombstone with same ip(s)
4198          */
4199         {
4200                 .line   = __location__,
4201                 .name   = _NBT_NAME("_UR_MT_SI", 0x00, NULL),
4202                 .wins   = {
4203                         .nb_flags       = 0,
4204                         .mhomed         = False,
4205                         .num_ips        = ctx->addresses_1_num,
4206                         .ips            = ctx->addresses_1,
4207                         .apply_expected = True
4208                 },
4209                 .replica= {
4210                         .type           = WREPL_TYPE_MHOMED,
4211                         .state          = WREPL_STATE_TOMBSTONE,
4212                         .node           = WREPL_NODE_B,
4213                         .is_static      = False,
4214                         .num_ips        = ctx->addresses_1_num,
4215                         .ips            = ctx->addresses_1,
4216                         .apply_expected = True
4217                 },
4218         },
4219         /*
4220          * unique,released vs. mhomed,tombstone with different ip(s)
4221          */
4222         {
4223                 .line   = __location__,
4224                 .name   = _NBT_NAME("_UR_MT_DI", 0x00, NULL),
4225                 .wins   = {
4226                         .nb_flags       = 0,
4227                         .mhomed         = False,
4228                         .num_ips        = ctx->addresses_1_num,
4229                         .ips            = ctx->addresses_1,
4230                         .apply_expected = True
4231                 },
4232                 .replica= {
4233                         .type           = WREPL_TYPE_MHOMED,
4234                         .state          = WREPL_STATE_TOMBSTONE,
4235                         .node           = WREPL_NODE_B,
4236                         .is_static      = False,
4237                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4238                         .ips            = addresses_B_1,
4239                         .apply_expected = True
4240                 },
4241         },
4242 /* 
4243  * group vs. unique section
4244  */
4245         /*
4246          * group,released vs. unique,active with same ip(s)
4247          */
4248         {
4249                 .line   = __location__,
4250                 .name   = _NBT_NAME("_GR_UA_SI", 0x00, NULL),
4251                 .wins   = {
4252                         .nb_flags       = NBT_NM_GROUP,
4253                         .mhomed         = False,
4254                         .num_ips        = ctx->addresses_1_num,
4255                         .ips            = ctx->addresses_1,
4256                         .apply_expected = True
4257                 },
4258                 .replica= {
4259                         .type           = WREPL_TYPE_UNIQUE,
4260                         .state          = WREPL_STATE_ACTIVE,
4261                         .node           = WREPL_NODE_B,
4262                         .is_static      = False,
4263                         .num_ips        = ctx->addresses_1_num,
4264                         .ips            = ctx->addresses_1,
4265                         .apply_expected = False
4266                 },
4267         },
4268         /*
4269          * group,released vs. unique,active with different ip(s)
4270          */
4271         {
4272                 .line   = __location__,
4273                 .name   = _NBT_NAME("_GR_UA_DI", 0x00, NULL),
4274                 .wins   = {
4275                         .nb_flags       = NBT_NM_GROUP,
4276                         .mhomed         = False,
4277                         .num_ips        = ctx->addresses_1_num,
4278                         .ips            = ctx->addresses_1,
4279                         .apply_expected = True
4280                 },
4281                 .replica= {
4282                         .type           = WREPL_TYPE_UNIQUE,
4283                         .state          = WREPL_STATE_ACTIVE,
4284                         .node           = WREPL_NODE_B,
4285                         .is_static      = False,
4286                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4287                         .ips            = addresses_B_1,
4288                         .apply_expected = False
4289                 },
4290         },
4291         /*
4292          * group,released vs. unique,tombstone with same ip(s)
4293          */
4294         {
4295                 .line   = __location__,
4296                 .name   = _NBT_NAME("_GR_UT_SI", 0x00, NULL),
4297                 .wins   = {
4298                         .nb_flags       = NBT_NM_GROUP,
4299                         .mhomed         = False,
4300                         .num_ips        = ctx->addresses_1_num,
4301                         .ips            = ctx->addresses_1,
4302                         .apply_expected = True
4303                 },
4304                 .replica= {
4305                         .type           = WREPL_TYPE_UNIQUE,
4306                         .state          = WREPL_STATE_TOMBSTONE,
4307                         .node           = WREPL_NODE_B,
4308                         .is_static      = False,
4309                         .num_ips        = ctx->addresses_1_num,
4310                         .ips            = ctx->addresses_1,
4311                         .apply_expected = False
4312                 },
4313         },
4314         /*
4315          * group,released vs. unique,tombstone with different ip(s)
4316          */
4317         {
4318                 .line   = __location__,
4319                 .name   = _NBT_NAME("_GR_UT_DI", 0x00, NULL),
4320                 .wins   = {
4321                         .nb_flags       = NBT_NM_GROUP,
4322                         .mhomed         = False,
4323                         .num_ips        = ctx->addresses_1_num,
4324                         .ips            = ctx->addresses_1,
4325                         .apply_expected = True
4326                 },
4327                 .replica= {
4328                         .type           = WREPL_TYPE_UNIQUE,
4329                         .state          = WREPL_STATE_TOMBSTONE,
4330                         .node           = WREPL_NODE_B,
4331                         .is_static      = False,
4332                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4333                         .ips            = addresses_B_1,
4334                         .apply_expected = False
4335                 },
4336         },
4337 /* 
4338  * group vs. group section
4339  */
4340         /*
4341          * group,released vs. group,active with same ip(s)
4342          */
4343         {
4344                 .line   = __location__,
4345                 .name   = _NBT_NAME("_GR_GA_SI", 0x00, NULL),
4346                 .wins   = {
4347                         .nb_flags       = NBT_NM_GROUP,
4348                         .mhomed         = False,
4349                         .num_ips        = ctx->addresses_1_num,
4350                         .ips            = ctx->addresses_1,
4351                         .apply_expected = True
4352                 },
4353                 .replica= {
4354                         .type           = WREPL_TYPE_GROUP,
4355                         .state          = WREPL_STATE_ACTIVE,
4356                         .node           = WREPL_NODE_B,
4357                         .is_static      = False,
4358                         .num_ips        = ctx->addresses_1_num,
4359                         .ips            = ctx->addresses_1,
4360                         .apply_expected = True
4361                 },
4362         },
4363         /*
4364          * group,released vs. group,active with different ip(s)
4365          */
4366         {
4367                 .line   = __location__,
4368                 .name   = _NBT_NAME("_GR_GA_DI", 0x00, NULL),
4369                 .wins   = {
4370                         .nb_flags       = NBT_NM_GROUP,
4371                         .mhomed         = False,
4372                         .num_ips        = ctx->addresses_1_num,
4373                         .ips            = ctx->addresses_1,
4374                         .apply_expected = True
4375                 },
4376                 .replica= {
4377                         .type           = WREPL_TYPE_GROUP,
4378                         .state          = WREPL_STATE_ACTIVE,
4379                         .node           = WREPL_NODE_B,
4380                         .is_static      = False,
4381                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4382                         .ips            = addresses_B_1,
4383                         .apply_expected = True
4384                 },
4385         },
4386         /*
4387          * group,released vs. group,tombstone with same ip(s)
4388          */
4389         {
4390                 .line   = __location__,
4391                 .name   = _NBT_NAME("_GR_GT_SI", 0x00, NULL),
4392                 .wins   = {
4393                         .nb_flags       = NBT_NM_GROUP,
4394                         .mhomed         = False,
4395                         .num_ips        = ctx->addresses_1_num,
4396                         .ips            = ctx->addresses_1,
4397                         .apply_expected = True
4398                 },
4399                 .replica= {
4400                         .type           = WREPL_TYPE_GROUP,
4401                         .state          = WREPL_STATE_TOMBSTONE,
4402                         .node           = WREPL_NODE_B,
4403                         .is_static      = False,
4404                         .num_ips        = ctx->addresses_1_num,
4405                         .ips            = ctx->addresses_1,
4406                         .apply_expected = True
4407                 },
4408         },
4409         /*
4410          * group,released vs. group,tombstone with different ip(s)
4411          */
4412         {
4413                 .line   = __location__,
4414                 .name   = _NBT_NAME("_GR_GT_DI", 0x00, NULL),
4415                 .wins   = {
4416                         .nb_flags       = NBT_NM_GROUP,
4417                         .mhomed         = False,
4418                         .num_ips        = ctx->addresses_1_num,
4419                         .ips            = ctx->addresses_1,
4420                         .apply_expected = True
4421                 },
4422                 .replica= {
4423                         .type           = WREPL_TYPE_GROUP,
4424                         .state          = WREPL_STATE_TOMBSTONE,
4425                         .node           = WREPL_NODE_B,
4426                         .is_static      = False,
4427                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4428                         .ips            = addresses_B_1,
4429                         .apply_expected = True
4430                 },
4431         },
4432 /* 
4433  * group vs. special group section
4434  */
4435         /*
4436          * group,released vs. sgroup,active with same ip(s)
4437          */
4438         {
4439                 .line   = __location__,
4440                 .name   = _NBT_NAME("_GR_SA_SI", 0x00, NULL),
4441                 .wins   = {
4442                         .nb_flags       = NBT_NM_GROUP,
4443                         .mhomed         = False,
4444                         .num_ips        = ctx->addresses_1_num,
4445                         .ips            = ctx->addresses_1,
4446                         .apply_expected = True
4447                 },
4448                 .replica= {
4449                         .type           = WREPL_TYPE_SGROUP,
4450                         .state          = WREPL_STATE_ACTIVE,
4451                         .node           = WREPL_NODE_B,
4452                         .is_static      = False,
4453                         .num_ips        = ctx->addresses_1_num,
4454                         .ips            = ctx->addresses_1,
4455                         .apply_expected = False
4456                 },
4457         },
4458         /*
4459          * group,released vs. sgroup,active with different ip(s)
4460          */
4461         {
4462                 .line   = __location__,
4463                 .name   = _NBT_NAME("_GR_SA_DI", 0x00, NULL),
4464                 .wins   = {
4465                         .nb_flags       = NBT_NM_GROUP,
4466                         .mhomed         = False,
4467                         .num_ips        = ctx->addresses_1_num,
4468                         .ips            = ctx->addresses_1,
4469                         .apply_expected = True
4470                 },
4471                 .replica= {
4472                         .type           = WREPL_TYPE_SGROUP,
4473                         .state          = WREPL_STATE_ACTIVE,
4474                         .node           = WREPL_NODE_B,
4475                         .is_static      = False,
4476                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4477                         .ips            = addresses_B_1,
4478                         .apply_expected = False
4479                 },
4480         },
4481         /*
4482          * group,released vs. sgroup,tombstone with same ip(s)
4483          */
4484         {
4485                 .line   = __location__,
4486                 .name   = _NBT_NAME("_GR_ST_SI", 0x00, NULL),
4487                 .wins   = {
4488                         .nb_flags       = NBT_NM_GROUP,
4489                         .mhomed         = False,
4490                         .num_ips        = ctx->addresses_1_num,
4491                         .ips            = ctx->addresses_1,
4492                         .apply_expected = True
4493                 },
4494                 .replica= {
4495                         .type           = WREPL_TYPE_SGROUP,
4496                         .state          = WREPL_STATE_TOMBSTONE,
4497                         .node           = WREPL_NODE_B,
4498                         .is_static      = False,
4499                         .num_ips        = ctx->addresses_1_num,
4500                         .ips            = ctx->addresses_1,
4501                         .apply_expected = False
4502                 },
4503         },
4504         /*
4505          * group,released vs. sgroup,tombstone with different ip(s)
4506          */
4507         {
4508                 .line   = __location__,
4509                 .name   = _NBT_NAME("_GR_ST_DI", 0x00, NULL),
4510                 .wins   = {
4511                         .nb_flags       = NBT_NM_GROUP,
4512                         .mhomed         = False,
4513                         .num_ips        = ctx->addresses_1_num,
4514                         .ips            = ctx->addresses_1,
4515                         .apply_expected = True
4516                 },
4517                 .replica= {
4518                         .type           = WREPL_TYPE_SGROUP,
4519                         .state          = WREPL_STATE_TOMBSTONE,
4520                         .node           = WREPL_NODE_B,
4521                         .is_static      = False,
4522                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4523                         .ips            = addresses_B_1,
4524                         .apply_expected = False
4525                 },
4526         },
4527 /* 
4528  * group vs. multi homed section
4529  */
4530         /*
4531          * group,released vs. mhomed,active with same ip(s)
4532          */
4533         {
4534                 .line   = __location__,
4535                 .name   = _NBT_NAME("_GR_MA_SI", 0x00, NULL),
4536                 .wins   = {
4537                         .nb_flags       = NBT_NM_GROUP,
4538                         .mhomed         = False,
4539                         .num_ips        = ctx->addresses_1_num,
4540                         .ips            = ctx->addresses_1,
4541                         .apply_expected = True
4542                 },
4543                 .replica= {
4544                         .type           = WREPL_TYPE_MHOMED,
4545                         .state          = WREPL_STATE_ACTIVE,
4546                         .node           = WREPL_NODE_B,
4547                         .is_static      = False,
4548                         .num_ips        = ctx->addresses_1_num,
4549                         .ips            = ctx->addresses_1,
4550                         .apply_expected = False
4551                 },
4552         },
4553         /*
4554          * group,released vs. mhomed,active with different ip(s)
4555          */
4556         {
4557                 .line   = __location__,
4558                 .name   = _NBT_NAME("_GR_MA_DI", 0x00, NULL),
4559                 .wins   = {
4560                         .nb_flags       = NBT_NM_GROUP,
4561                         .mhomed         = False,
4562                         .num_ips        = ctx->addresses_1_num,
4563                         .ips            = ctx->addresses_1,
4564                         .apply_expected = True
4565                 },
4566                 .replica= {
4567                         .type           = WREPL_TYPE_MHOMED,
4568                         .state          = WREPL_STATE_ACTIVE,
4569                         .node           = WREPL_NODE_B,
4570                         .is_static      = False,
4571                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4572                         .ips            = addresses_B_1,
4573                         .apply_expected = False
4574                 },
4575         },
4576         /*
4577          * group,released vs. mhomed,tombstone with same ip(s)
4578          */
4579         {
4580                 .line   = __location__,
4581                 .name   = _NBT_NAME("_GR_MT_SI", 0x00, NULL),
4582                 .wins   = {
4583                         .nb_flags       = NBT_NM_GROUP,
4584                         .mhomed         = False,
4585                         .num_ips        = ctx->addresses_1_num,
4586                         .ips            = ctx->addresses_1,
4587                         .apply_expected = True
4588                 },
4589                 .replica= {
4590                         .type           = WREPL_TYPE_MHOMED,
4591                         .state          = WREPL_STATE_TOMBSTONE,
4592                         .node           = WREPL_NODE_B,
4593                         .is_static      = False,
4594                         .num_ips        = ctx->addresses_1_num,
4595                         .ips            = ctx->addresses_1,
4596                         .apply_expected = False
4597                 },
4598         },
4599         /*
4600          * group,released vs. mhomed,tombstone with different ip(s)
4601          */
4602         {
4603                 .line   = __location__,
4604                 .name   = _NBT_NAME("_GR_MT_DI", 0x00, NULL),
4605                 .wins   = {
4606                         .nb_flags       = NBT_NM_GROUP,
4607                         .mhomed         = False,
4608                         .num_ips        = ctx->addresses_1_num,
4609                         .ips            = ctx->addresses_1,
4610                         .apply_expected = True
4611                 },
4612                 .replica= {
4613                         .type           = WREPL_TYPE_MHOMED,
4614                         .state          = WREPL_STATE_TOMBSTONE,
4615                         .node           = WREPL_NODE_B,
4616                         .is_static      = False,
4617                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4618                         .ips            = addresses_B_1,
4619                         .apply_expected = False
4620                 },
4621         },
4622 /* 
4623  * special group vs. unique section
4624  */
4625         /*
4626          * sgroup,released vs. unique,active with same ip(s)
4627          */
4628         {
4629                 .line   = __location__,
4630                 .name   = _NBT_NAME("_SR_UA_SI", 0x1C, NULL),
4631                 .wins   = {
4632                         .nb_flags       = NBT_NM_GROUP,
4633                         .mhomed         = False,
4634                         .num_ips        = ctx->addresses_1_num,
4635                         .ips            = ctx->addresses_1,
4636                         .apply_expected = True
4637                 },
4638                 .replica= {
4639                         .type           = WREPL_TYPE_UNIQUE,
4640                         .state          = WREPL_STATE_ACTIVE,
4641                         .node           = WREPL_NODE_B,
4642                         .is_static      = False,
4643                         .num_ips        = ctx->addresses_1_num,
4644                         .ips            = ctx->addresses_1,
4645                         .apply_expected = True
4646                 },
4647         },
4648         /*
4649          * sgroup,released vs. unique,active with different ip(s)
4650          */
4651         {
4652                 .line   = __location__,
4653                 .name   = _NBT_NAME("_SR_UA_DI", 0x1C, NULL),
4654                 .wins   = {
4655                         .nb_flags       = NBT_NM_GROUP,
4656                         .mhomed         = False,
4657                         .num_ips        = ctx->addresses_1_num,
4658                         .ips            = ctx->addresses_1,
4659                         .apply_expected = True
4660                 },
4661                 .replica= {
4662                         .type           = WREPL_TYPE_UNIQUE,
4663                         .state          = WREPL_STATE_ACTIVE,
4664                         .node           = WREPL_NODE_B,
4665                         .is_static      = False,
4666                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4667                         .ips            = addresses_B_1,
4668                         .apply_expected = True
4669                 },
4670         },
4671         /*
4672          * sgroup,released vs. unique,tombstone with same ip(s)
4673          */
4674         {
4675                 .line   = __location__,
4676                 .name   = _NBT_NAME("_SR_UT_SI", 0x1C, NULL),
4677                 .wins   = {
4678                         .nb_flags       = NBT_NM_GROUP,
4679                         .mhomed         = False,
4680                         .num_ips        = ctx->addresses_1_num,
4681                         .ips            = ctx->addresses_1,
4682                         .apply_expected = True
4683                 },
4684                 .replica= {
4685                         .type           = WREPL_TYPE_UNIQUE,
4686                         .state          = WREPL_STATE_TOMBSTONE,
4687                         .node           = WREPL_NODE_B,
4688                         .is_static      = False,
4689                         .num_ips        = ctx->addresses_1_num,
4690                         .ips            = ctx->addresses_1,
4691                         .apply_expected = True
4692                 },
4693         },
4694         /*
4695          * sgroup,released vs. unique,tombstone with different ip(s)
4696          */
4697         {
4698                 .line   = __location__,
4699                 .name   = _NBT_NAME("_SR_UT_DI", 0x1C, NULL),
4700                 .wins   = {
4701                         .nb_flags       = NBT_NM_GROUP,
4702                         .mhomed         = False,
4703                         .num_ips        = ctx->addresses_1_num,
4704                         .ips            = ctx->addresses_1,
4705                         .apply_expected = True
4706                 },
4707                 .replica= {
4708                         .type           = WREPL_TYPE_UNIQUE,
4709                         .state          = WREPL_STATE_TOMBSTONE,
4710                         .node           = WREPL_NODE_B,
4711                         .is_static      = False,
4712                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4713                         .ips            = addresses_B_1,
4714                         .apply_expected = True
4715                 },
4716         },
4717 /* 
4718  * special group vs. group section
4719  */
4720         /*
4721          * sgroup,released vs. group,active with same ip(s)
4722          */
4723         {
4724                 .line   = __location__,
4725                 .name   = _NBT_NAME("_SR_GA_SI", 0x1C, NULL),
4726                 .wins   = {
4727                         .nb_flags       = NBT_NM_GROUP,
4728                         .mhomed         = False,
4729                         .num_ips        = ctx->addresses_1_num,
4730                         .ips            = ctx->addresses_1,
4731                         .apply_expected = True
4732                 },
4733                 .replica= {
4734                         .type           = WREPL_TYPE_GROUP,
4735                         .state          = WREPL_STATE_ACTIVE,
4736                         .node           = WREPL_NODE_B,
4737                         .is_static      = False,
4738                         .num_ips        = ctx->addresses_1_num,
4739                         .ips            = ctx->addresses_1,
4740                         .apply_expected = True
4741                 },
4742         },
4743         /*
4744          * sgroup,released vs. group,active with different ip(s)
4745          */
4746         {
4747                 .line   = __location__,
4748                 .name   = _NBT_NAME("_SR_GA_DI", 0x1C, NULL),
4749                 .wins   = {
4750                         .nb_flags       = NBT_NM_GROUP,
4751                         .mhomed         = False,
4752                         .num_ips        = ctx->addresses_1_num,
4753                         .ips            = ctx->addresses_1,
4754                         .apply_expected = True
4755                 },
4756                 .replica= {
4757                         .type           = WREPL_TYPE_GROUP,
4758                         .state          = WREPL_STATE_ACTIVE,
4759                         .node           = WREPL_NODE_B,
4760                         .is_static      = False,
4761                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4762                         .ips            = addresses_B_1,
4763                         .apply_expected = True
4764                 },
4765         },
4766         /*
4767          * sgroup,released vs. group,tombstone with same ip(s)
4768          */
4769         {
4770                 .line   = __location__,
4771                 .name   = _NBT_NAME("_SR_GT_SI", 0x1C, NULL),
4772                 .wins   = {
4773                         .nb_flags       = NBT_NM_GROUP,
4774                         .mhomed         = False,
4775                         .num_ips        = ctx->addresses_1_num,
4776                         .ips            = ctx->addresses_1,
4777                         .apply_expected = True
4778                 },
4779                 .replica= {
4780                         .type           = WREPL_TYPE_GROUP,
4781                         .state          = WREPL_STATE_TOMBSTONE,
4782                         .node           = WREPL_NODE_B,
4783                         .is_static      = False,
4784                         .num_ips        = ctx->addresses_1_num,
4785                         .ips            = ctx->addresses_1,
4786                         .apply_expected = True
4787                 },
4788         },
4789         /*
4790          * sgroup,released vs. group,tombstone with different ip(s)
4791          */
4792         {
4793                 .line   = __location__,
4794                 .name   = _NBT_NAME("_SR_GT_DI", 0x1C, NULL),
4795                 .wins   = {
4796                         .nb_flags       = NBT_NM_GROUP,
4797                         .mhomed         = False,
4798                         .num_ips        = ctx->addresses_1_num,
4799                         .ips            = ctx->addresses_1,
4800                         .apply_expected = True
4801                 },
4802                 .replica= {
4803                         .type           = WREPL_TYPE_GROUP,
4804                         .state          = WREPL_STATE_TOMBSTONE,
4805                         .node           = WREPL_NODE_B,
4806                         .is_static      = False,
4807                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4808                         .ips            = addresses_B_1,
4809                         .apply_expected = True
4810                 },
4811         },
4812 /* 
4813  * special group vs. special group section
4814  */
4815         /*
4816          * sgroup,released vs. sgroup,active with same ip(s)
4817          */
4818         {
4819                 .line   = __location__,
4820                 .name   = _NBT_NAME("_SR_SA_SI", 0x1C, NULL),
4821                 .wins   = {
4822                         .nb_flags       = NBT_NM_GROUP,
4823                         .mhomed         = False,
4824                         .num_ips        = ctx->addresses_1_num,
4825                         .ips            = ctx->addresses_1,
4826                         .apply_expected = True
4827                 },
4828                 .replica= {
4829                         .type           = WREPL_TYPE_SGROUP,
4830                         .state          = WREPL_STATE_ACTIVE,
4831                         .node           = WREPL_NODE_B,
4832                         .is_static      = False,
4833                         .num_ips        = ctx->addresses_1_num,
4834                         .ips            = ctx->addresses_1,
4835                         .apply_expected = True
4836                 },
4837         },
4838         /*
4839          * sgroup,released vs. sgroup,active with different ip(s)
4840          */
4841         {
4842                 .line   = __location__,
4843                 .name   = _NBT_NAME("_SR_SA_DI", 0x1C, NULL),
4844                 .wins   = {
4845                         .nb_flags       = NBT_NM_GROUP,
4846                         .mhomed         = False,
4847                         .num_ips        = ctx->addresses_1_num,
4848                         .ips            = ctx->addresses_1,
4849                         .apply_expected = True
4850                 },
4851                 .replica= {
4852                         .type           = WREPL_TYPE_SGROUP,
4853                         .state          = WREPL_STATE_ACTIVE,
4854                         .node           = WREPL_NODE_B,
4855                         .is_static      = False,
4856                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4857                         .ips            = addresses_B_1,
4858                         .apply_expected = True
4859                 },
4860         },
4861         /*
4862          * sgroup,released vs. sgroup,tombstone with same ip(s)
4863          */
4864         {
4865                 .line   = __location__,
4866                 .name   = _NBT_NAME("_SR_ST_SI", 0x1C, NULL),
4867                 .wins   = {
4868                         .nb_flags       = NBT_NM_GROUP,
4869                         .mhomed         = False,
4870                         .num_ips        = ctx->addresses_1_num,
4871                         .ips            = ctx->addresses_1,
4872                         .apply_expected = True
4873                 },
4874                 .replica= {
4875                         .type           = WREPL_TYPE_SGROUP,
4876                         .state          = WREPL_STATE_TOMBSTONE,
4877                         .node           = WREPL_NODE_B,
4878                         .is_static      = False,
4879                         .num_ips        = ctx->addresses_1_num,
4880                         .ips            = ctx->addresses_1,
4881                         .apply_expected = True
4882                 },
4883         },
4884         /*
4885          * sgroup,released vs. sgroup,tombstone with different ip(s)
4886          */
4887         {
4888                 .line   = __location__,
4889                 .name   = _NBT_NAME("_SR_ST_DI", 0x1C, NULL),
4890                 .wins   = {
4891                         .nb_flags       = NBT_NM_GROUP,
4892                         .mhomed         = False,
4893                         .num_ips        = ctx->addresses_1_num,
4894                         .ips            = ctx->addresses_1,
4895                         .apply_expected = True
4896                 },
4897                 .replica= {
4898                         .type           = WREPL_TYPE_SGROUP,
4899                         .state          = WREPL_STATE_TOMBSTONE,
4900                         .node           = WREPL_NODE_B,
4901                         .is_static      = False,
4902                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4903                         .ips            = addresses_B_1,
4904                         .apply_expected = True
4905                 },
4906         },
4907 /* 
4908  * special group vs. multi homed section
4909  */
4910         /*
4911          * sgroup,released vs. mhomed,active with same ip(s)
4912          */
4913         {
4914                 .line   = __location__,
4915                 .name   = _NBT_NAME("_SR_MA_SI", 0x1C, NULL),
4916                 .wins   = {
4917                         .nb_flags       = NBT_NM_GROUP,
4918                         .mhomed         = False,
4919                         .num_ips        = ctx->addresses_1_num,
4920                         .ips            = ctx->addresses_1,
4921                         .apply_expected = True
4922                 },
4923                 .replica= {
4924                         .type           = WREPL_TYPE_MHOMED,
4925                         .state          = WREPL_STATE_ACTIVE,
4926                         .node           = WREPL_NODE_B,
4927                         .is_static      = False,
4928                         .num_ips        = ctx->addresses_1_num,
4929                         .ips            = ctx->addresses_1,
4930                         .apply_expected = True
4931                 },
4932         },
4933         /*
4934          * sgroup,released vs. mhomed,active with different ip(s)
4935          */
4936         {
4937                 .line   = __location__,
4938                 .name   = _NBT_NAME("_SR_MA_DI", 0x1C, NULL),
4939                 .wins   = {
4940                         .nb_flags       = NBT_NM_GROUP,
4941                         .mhomed         = False,
4942                         .num_ips        = ctx->addresses_1_num,
4943                         .ips            = ctx->addresses_1,
4944                         .apply_expected = True
4945                 },
4946                 .replica= {
4947                         .type           = WREPL_TYPE_MHOMED,
4948                         .state          = WREPL_STATE_ACTIVE,
4949                         .node           = WREPL_NODE_B,
4950                         .is_static      = False,
4951                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4952                         .ips            = addresses_B_1,
4953                         .apply_expected = True
4954                 },
4955         },
4956         /*
4957          * sgroup,released vs. mhomed,tombstone with same ip(s)
4958          */
4959         {
4960                 .line   = __location__,
4961                 .name   = _NBT_NAME("_SR_MT_SI", 0x1C, NULL),
4962                 .wins   = {
4963                         .nb_flags       = NBT_NM_GROUP,
4964                         .mhomed         = False,
4965                         .num_ips        = ctx->addresses_1_num,
4966                         .ips            = ctx->addresses_1,
4967                         .apply_expected = True
4968                 },
4969                 .replica= {
4970                         .type           = WREPL_TYPE_MHOMED,
4971                         .state          = WREPL_STATE_TOMBSTONE,
4972                         .node           = WREPL_NODE_B,
4973                         .is_static      = False,
4974                         .num_ips        = ctx->addresses_1_num,
4975                         .ips            = ctx->addresses_1,
4976                         .apply_expected = True
4977                 },
4978         },
4979         /*
4980          * sgroup,released vs. mhomed,tombstone with different ip(s)
4981          */
4982         {
4983                 .line   = __location__,
4984                 .name   = _NBT_NAME("_SR_MT_DI", 0x1C, NULL),
4985                 .wins   = {
4986                         .nb_flags       = NBT_NM_GROUP,
4987                         .mhomed         = False,
4988                         .num_ips        = ctx->addresses_1_num,
4989                         .ips            = ctx->addresses_1,
4990                         .apply_expected = True
4991                 },
4992                 .replica= {
4993                         .type           = WREPL_TYPE_MHOMED,
4994                         .state          = WREPL_STATE_TOMBSTONE,
4995                         .node           = WREPL_NODE_B,
4996                         .is_static      = False,
4997                         .num_ips        = ARRAY_SIZE(addresses_B_1),
4998                         .ips            = addresses_B_1,
4999                         .apply_expected = True
5000                 },
5001         },
5002 /* 
5003  * multi homed vs. unique section
5004  */
5005         /*
5006          * mhomed,released vs. unique,active with same ip(s)
5007          */
5008         {
5009                 .line   = __location__,
5010                 .name   = _NBT_NAME("_MR_UA_SI", 0x00, NULL),
5011                 .wins   = {
5012                         .nb_flags       = 0,
5013                         .mhomed         = True,
5014                         .num_ips        = ctx->addresses_1_num,
5015                         .ips            = ctx->addresses_1,
5016                         .apply_expected = True
5017                 },
5018                 .replica= {
5019                         .type           = WREPL_TYPE_UNIQUE,
5020                         .state          = WREPL_STATE_ACTIVE,
5021                         .node           = WREPL_NODE_B,
5022                         .is_static      = False,
5023                         .num_ips        = ctx->addresses_1_num,
5024                         .ips            = ctx->addresses_1,
5025                         .apply_expected = True
5026                 },
5027         },
5028         /*
5029          * mhomed,released vs. unique,active with different ip(s)
5030          */
5031         {
5032                 .line   = __location__,
5033                 .name   = _NBT_NAME("_MR_UA_DI", 0x00, NULL),
5034                 .wins   = {
5035                         .nb_flags       = 0,
5036                         .mhomed         = True,
5037                         .num_ips        = ctx->addresses_1_num,
5038                         .ips            = ctx->addresses_1,
5039                         .apply_expected = True
5040                 },
5041                 .replica= {
5042                         .type           = WREPL_TYPE_UNIQUE,
5043                         .state          = WREPL_STATE_ACTIVE,
5044                         .node           = WREPL_NODE_B,
5045                         .is_static      = False,
5046                         .num_ips        = ARRAY_SIZE(addresses_B_1),
5047                         .ips            = addresses_B_1,
5048                         .apply_expected = True
5049                 },
5050         },
5051         /*
5052          * mhomed,released vs. unique,tombstone with same ip(s)
5053          */
5054         {
5055                 .line   = __location__,
5056                 .name   = _NBT_NAME("_MR_UT_SI", 0x00, NULL),
5057                 .wins   = {
5058                         .nb_flags       = 0,
5059                         .mhomed         = True,
5060                         .num_ips        = ctx->addresses_1_num,
5061                         .ips            = ctx->addresses_1,
5062                         .apply_expected = True
5063                 },
5064                 .replica= {
5065                         .type           = WREPL_TYPE_UNIQUE,
5066                         .state          = WREPL_STATE_TOMBSTONE,
5067                         .node           = WREPL_NODE_B,
5068                         .is_static      = False,
5069                         .num_ips        = ctx->addresses_1_num,
5070                         .ips            = ctx->addresses_1,
5071                         .apply_expected = True
5072                 },
5073         },
5074         /*
5075          * mhomed,released vs. unique,tombstone with different ip(s)
5076          */
5077         {
5078                 .line   = __location__,
5079                 .name   = _NBT_NAME("_MR_UT_DI", 0x00, NULL),
5080                 .wins   = {
5081                         .nb_flags       = 0,
5082                         .mhomed         = True,
5083                         .num_ips        = ctx->addresses_1_num,
5084                         .ips            = ctx->addresses_1,
5085                         .apply_expected = True
5086                 },
5087                 .replica= {
5088                         .type           = WREPL_TYPE_UNIQUE,
5089                         .state          = WREPL_STATE_TOMBSTONE,
5090                         .node           = WREPL_NODE_B,
5091                         .is_static      = False,
5092                         .num_ips        = ARRAY_SIZE(addresses_B_1),
5093                         .ips            = addresses_B_1,
5094                         .apply_expected = True
5095                 },
5096         },
5097 /* 
5098  * multi homed vs. group section
5099  */
5100         /*
5101          * mhomed,released vs. group,active with same ip(s)
5102          */
5103         {
5104                 .line   = __location__,
5105                 .name   = _NBT_NAME("_MR_GA_SI", 0x00, NULL),
5106                 .wins   = {
5107                         .nb_flags       = 0,
5108                         .mhomed         = True,
5109                         .num_ips        = ctx->addresses_1_num,
5110                         .ips            = ctx->addresses_1,
5111                         .apply_expected = True
5112                 },
5113                 .replica= {
5114                         .type           = WREPL_TYPE_GROUP,
5115                         .state          = WREPL_STATE_ACTIVE,
5116                         .node           = WREPL_NODE_B,
5117                         .is_static      = False,
5118                         .num_ips        = ctx->addresses_1_num,
5119                         .ips            = ctx->addresses_1,
5120                         .apply_expected = True
5121                 },
5122         },
5123         /*
5124          * mhomed,released vs. group,active with different ip(s)
5125          */
5126         {
5127                 .line   = __location__,
5128                 .name   = _NBT_NAME("_MR_GA_DI", 0x00, NULL),
5129                 .wins   = {
5130                         .nb_flags       = 0,
5131                         .mhomed         = True,
5132                         .num_ips        = ctx->addresses_1_num,
5133                         .ips            = ctx->addresses_1,
5134                         .apply_expected = True
5135                 },
5136                 .replica= {
5137                         .type           = WREPL_TYPE_GROUP,
5138                         .state          = WREPL_STATE_ACTIVE,
5139                         .node           = WREPL_NODE_B,
5140                         .is_static      = False,
5141                         .num_ips        = ARRAY_SIZE(addresses_B_1),
5142                         .ips            = addresses_B_1,
5143                         .apply_expected = True
5144                 },
5145         },
5146         /*
5147          * mhomed,released vs. group,tombstone with same ip(s)
5148          */
5149         {
5150                 .line   = __location__,
5151                 .name   = _NBT_NAME("_MR_GT_SI", 0x00, NULL),
5152                 .wins   = {
5153                         .nb_flags       = 0,
5154                         .mhomed         = True,
5155                         .num_ips        = ctx->addresses_1_num,
5156                         .ips            = ctx->addresses_1,
5157                         .apply_expected = True
5158                 },
5159                 .replica= {
5160                         .type           = WREPL_TYPE_GROUP,
5161                         .state          = WREPL_STATE_TOMBSTONE,
5162                         .node           = WREPL_NODE_B,
5163                         .is_static      = False,
5164                         .num_ips        = ctx->addresses_1_num,
5165                         .ips            = ctx->addresses_1,
5166                         .apply_expected = True
5167                 },
5168         },
5169         /*
5170          * mhomed,released vs. group,tombstone with different ip(s)
5171          */
5172         {
5173                 .line   = __location__,
5174                 .name   = _NBT_NAME("_MR_GT_DI", 0x00, NULL),
5175                 .wins   = {
5176                         .nb_flags       = 0,
5177                         .mhomed         = True,
5178                         .num_ips        = ctx->addresses_1_num,
5179                         .ips            = ctx->addresses_1,
5180                         .apply_expected = True
5181                 },
5182                 .replica= {
5183                         .type           = WREPL_TYPE_GROUP,
5184                         .state          = WREPL_STATE_TOMBSTONE,
5185                         .node           = WREPL_NODE_B,
5186                         .is_static      = False,
5187                         .num_ips        = ARRAY_SIZE(addresses_B_1),
5188                         .ips            = addresses_B_1,
5189                         .apply_expected = True
5190                 },
5191         },
5192 /* 
5193  * multi homed vs. special group section
5194  */
5195         /*
5196          * mhomed,released vs. sgroup,active with same ip(s)
5197          */
5198         {
5199                 .line   = __location__,
5200                 .name   = _NBT_NAME("_MR_SA_SI", 0x00, NULL),
5201                 .wins   = {
5202                         .nb_flags       = 0,
5203                         .mhomed         = True,
5204                         .num_ips        = ctx->addresses_1_num,
5205                         .ips            = ctx->addresses_1,
5206                         .apply_expected = True
5207                 },
5208                 .replica= {
5209                         .type           = WREPL_TYPE_SGROUP,
5210                         .state          = WREPL_STATE_ACTIVE,
5211                         .node           = WREPL_NODE_B,
5212                         .is_static      = False,
5213                         .num_ips        = ctx->addresses_1_num,
5214                         .ips            = ctx->addresses_1,
5215                         .apply_expected = True
5216                 },
5217         },
5218         /*
5219          * mhomed,released vs. sgroup,active with different ip(s)
5220          */
5221         {
5222                 .line   = __location__,
5223                 .name   = _NBT_NAME("_MR_SA_DI", 0x00, NULL),
5224                 .wins   = {
5225                         .nb_flags       = 0,
5226                         .mhomed         = True,
5227                         .num_ips        = ctx->addresses_1_num,
5228                         .ips            = ctx->addresses_1,
5229                         .apply_expected = True
5230                 },
5231                 .replica= {
5232                         .type           = WREPL_TYPE_SGROUP,
5233                         .state          = WREPL_STATE_ACTIVE,
5234                         .node           = WREPL_NODE_B,
5235                         .is_static      = False,
5236                         .num_ips        = ARRAY_SIZE(addresses_B_1),
5237                         .ips            = addresses_B_1,
5238                         .apply_expected = True
5239                 },
5240         },
5241         /*
5242          * mhomed,released vs. sgroup,tombstone with same ip(s)
5243          */
5244         {
5245                 .line   = __location__,
5246                 .name   = _NBT_NAME("_MR_ST_SI", 0x00, NULL),
5247                 .wins   = {
5248                         .nb_flags       = 0,
5249                         .mhomed         = True,
5250                         .num_ips        = ctx->addresses_1_num,
5251                         .ips            = ctx->addresses_1,
5252                         .apply_expected = True
5253                 },
5254                 .replica= {
5255                         .type           = WREPL_TYPE_SGROUP,
5256                         .state          = WREPL_STATE_TOMBSTONE,
5257                         .node           = WREPL_NODE_B,
5258                         .is_static      = False,
5259                         .num_ips        = ctx->addresses_1_num,
5260                         .ips            = ctx->addresses_1,
5261                         .apply_expected = True
5262                 },
5263         },
5264         /*
5265          * mhomed,released vs. sgroup,tombstone with different ip(s)
5266          */
5267         {
5268                 .line   = __location__,
5269                 .name   = _NBT_NAME("_MR_ST_DI", 0x00, NULL),
5270                 .wins   = {
5271                         .nb_flags       = 0,
5272                         .mhomed         = True,
5273                         .num_ips        = ctx->addresses_1_num,
5274                         .ips            = ctx->addresses_1,
5275                         .apply_expected = True
5276                 },
5277                 .replica= {
5278                         .type           = WREPL_TYPE_SGROUP,
5279                         .state          = WREPL_STATE_TOMBSTONE,
5280                         .node           = WREPL_NODE_B,
5281                         .is_static      = False,
5282                         .num_ips        = ARRAY_SIZE(addresses_B_1),
5283                         .ips            = addresses_B_1,
5284                         .apply_expected = True
5285                 },
5286         },
5287 /* 
5288  * multi homed vs. multi homed section
5289  */
5290         /*
5291          * mhomed,released vs. mhomed,active with same ip(s)
5292          */
5293         {
5294                 .line   = __location__,
5295                 .name   = _NBT_NAME("_MR_MA_SI", 0x00, NULL),
5296                 .wins   = {
5297                         .nb_flags       = 0,
5298                         .mhomed         = True,
5299                         .num_ips        = ctx->addresses_1_num,
5300                         .ips            = ctx->addresses_1,
5301                         .apply_expected = True
5302                 },
5303                 .replica= {
5304                         .type           = WREPL_TYPE_MHOMED,
5305                         .state          = WREPL_STATE_ACTIVE,
5306                         .node           = WREPL_NODE_B,
5307                         .is_static      = False,
5308                         .num_ips        = ctx->addresses_1_num,
5309                         .ips            = ctx->addresses_1,
5310                         .apply_expected = True
5311                 },
5312         },
5313         /*
5314          * mhomed,released vs. mhomed,active with different ip(s)
5315          */
5316         {
5317                 .line   = __location__,
5318                 .name   = _NBT_NAME("_MR_MA_DI", 0x00, NULL),
5319                 .wins   = {
5320                         .nb_flags       = 0,
5321                         .mhomed         = True,
5322                         .num_ips        = ctx->addresses_1_num,
5323                         .ips            = ctx->addresses_1,
5324                         .apply_expected = True
5325                 },
5326                 .replica= {
5327                         .type           = WREPL_TYPE_MHOMED,
5328                         .state          = WREPL_STATE_ACTIVE,
5329                         .node           = WREPL_NODE_B,
5330                         .is_static      = False,
5331                         .num_ips        = ARRAY_SIZE(addresses_B_1),
5332                         .ips            = addresses_B_1,
5333                         .apply_expected = True
5334                 },
5335         },
5336         /*
5337          * mhomed,released vs. mhomed,tombstone with same ip(s)
5338          */
5339         {
5340                 .line   = __location__,
5341                 .name   = _NBT_NAME("_MR_MT_SI", 0x00, NULL),
5342                 .wins   = {
5343                         .nb_flags       = 0,
5344                         .mhomed         = True,
5345                         .num_ips        = ctx->addresses_1_num,
5346                         .ips            = ctx->addresses_1,
5347                         .apply_expected = True
5348                 },
5349                 .replica= {
5350                         .type           = WREPL_TYPE_MHOMED,
5351                         .state          = WREPL_STATE_TOMBSTONE,
5352                         .node           = WREPL_NODE_B,
5353                         .is_static      = False,
5354                         .num_ips        = ctx->addresses_1_num,
5355                         .ips            = ctx->addresses_1,
5356                         .apply_expected = True
5357                 },
5358         },
5359         /*
5360          * mhomed,released vs. mhomed,tombstone with different ip(s)
5361          */
5362         {
5363                 .line   = __location__,
5364                 .name   = _NBT_NAME("_MR_MT_DI", 0x00, NULL),
5365                 .wins   = {
5366                         .nb_flags       = 0,
5367                         .mhomed         = True,
5368                         .num_ips        = ctx->addresses_1_num,
5369                         .ips            = ctx->addresses_1,
5370                         .apply_expected = True
5371                 },
5372                 .replica= {
5373                         .type           = WREPL_TYPE_MHOMED,
5374                         .state          = WREPL_STATE_TOMBSTONE,
5375                         .node           = WREPL_NODE_B,
5376                         .is_static      = False,
5377                         .num_ips        = ARRAY_SIZE(addresses_B_1),
5378                         .ips            = addresses_B_1,
5379                         .apply_expected = True
5380                 },
5381         },
5382         };
5383
5384         if (!ctx) return False;
5385
5386         printf("Test Replica records vs. owned released records\n");
5387
5388         for(i=0; ret && i < ARRAY_SIZE(records); i++) {
5389                 printf("%s => %s\n", nbt_name_string(ctx, &records[i].name),
5390                         (records[i].replica.apply_expected?"REPLACE":"NOT REPLACE"));
5391
5392                 /*
5393                  * Setup Register
5394                  */
5395                 name_register->in.name          = records[i].name;
5396                 name_register->in.dest_addr     = ctx->address;
5397                 name_register->in.address       = records[i].wins.ips[0].ip;
5398                 name_register->in.nb_flags      = records[i].wins.nb_flags;
5399                 name_register->in.register_demand= False;
5400                 name_register->in.broadcast     = False;
5401                 name_register->in.multi_homed   = records[i].wins.mhomed;
5402                 name_register->in.ttl           = 300000;
5403                 name_register->in.timeout       = 70;
5404                 name_register->in.retries       = 0;
5405
5406                 status = nbt_name_register(ctx->nbtsock, ctx, name_register);
5407                 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
5408                         printf("No response from %s for name register\n", ctx->address);
5409                         ret = False;
5410                 }
5411                 if (!NT_STATUS_IS_OK(status)) {
5412                         printf("Bad response from %s for name register - %s\n",
5413                                ctx->address, nt_errstr(status));
5414                         ret = False;
5415                 }
5416                 CHECK_VALUE(name_register->out.rcode, 0);
5417                 CHECK_VALUE_STRING(name_register->out.reply_from, ctx->address);
5418                 CHECK_VALUE(name_register->out.name.type, records[i].name.type);
5419                 CHECK_VALUE_STRING(name_register->out.name.name, records[i].name.name);
5420                 CHECK_VALUE_STRING(name_register->out.name.scope, records[i].name.scope);
5421                 CHECK_VALUE_STRING(name_register->out.reply_addr, records[i].wins.ips[0].ip);
5422
5423                 /* release the record */
5424                 release->in.name        = records[i].name;
5425                 release->in.dest_addr   = ctx->address;
5426                 release->in.address     = records[i].wins.ips[0].ip;
5427                 release->in.nb_flags    = records[i].wins.nb_flags;
5428                 release->in.broadcast   = False;
5429                 release->in.timeout     = 30;
5430                 release->in.retries     = 0;
5431
5432                 status = nbt_name_release(ctx->nbtsock, ctx, release);
5433                 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
5434                         printf("No response from %s for name release\n", ctx->address);
5435                         return False;
5436                 }
5437                 if (!NT_STATUS_IS_OK(status)) {
5438                         printf("Bad response from %s for name query - %s\n",
5439                                ctx->address, nt_errstr(status));
5440                         return False;
5441                 }
5442                 CHECK_VALUE(release->out.rcode, 0);
5443
5444                 /*
5445                  * Setup Replica
5446                  */
5447                 wins_name->name         = &records[i].name;
5448                 wins_name->flags        = WREPL_NAME_FLAGS(records[i].replica.type,
5449                                                            records[i].replica.state,
5450                                                            records[i].replica.node,
5451                                                            records[i].replica.is_static);
5452                 wins_name->id           = ++ctx->b.max_version;
5453                 if (wins_name->flags & 2) {
5454                         wins_name->addresses.addresses.num_ips = records[i].replica.num_ips;
5455                         wins_name->addresses.addresses.ips     = discard_const(records[i].replica.ips);
5456                 } else {
5457                         wins_name->addresses.ip = records[i].replica.ips[0].ip;
5458                 }
5459                 wins_name->unknown      = "255.255.255.255";
5460
5461                 ret &= test_wrepl_update_one(ctx, &ctx->b, wins_name);
5462                 ret &= test_wrepl_is_applied(ctx, &ctx->b, wins_name,
5463                                              records[i].replica.apply_expected);
5464
5465                 if (records[i].replica.apply_expected) {
5466                         wins_name->name         = &records[i].name;
5467                         wins_name->flags        = WREPL_NAME_FLAGS(WREPL_TYPE_UNIQUE,
5468                                                                    WREPL_STATE_TOMBSTONE,
5469                                                                    WREPL_NODE_B, False);
5470                         wins_name->id           = ++ctx->b.max_version;
5471                         wins_name->addresses.ip = addresses_B_1[0].ip;
5472                         wins_name->unknown      = "255.255.255.255";
5473
5474                         ret &= test_wrepl_update_one(ctx, &ctx->b, wins_name);
5475                         ret &= test_wrepl_is_applied(ctx, &ctx->b, wins_name, True);
5476                 } else {
5477                         release->in.name        = records[i].name;
5478                         release->in.dest_addr   = ctx->address;
5479                         release->in.address     = records[i].wins.ips[0].ip;
5480                         release->in.nb_flags    = records[i].wins.nb_flags;
5481                         release->in.broadcast   = False;
5482                         release->in.timeout     = 30;
5483                         release->in.retries     = 0;
5484
5485                         status = nbt_name_release(ctx->nbtsock, ctx, release);
5486                         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
5487                                 printf("No response from %s for name release\n", ctx->address);
5488                                 return False;
5489                         }
5490                         if (!NT_STATUS_IS_OK(status)) {
5491                                 printf("Bad response from %s for name query - %s\n",
5492                                        ctx->address, nt_errstr(status));
5493                                 return False;
5494                         }
5495                         CHECK_VALUE(release->out.rcode, 0);
5496                 }
5497 done:
5498                 if (!ret) {
5499                         printf("conflict handled wrong or record[%u]: %s\n", i, records[i].line);
5500                         return ret;
5501                 }
5502         }
5503
5504         return ret;
5505 }
5506
5507 struct test_conflict_owned_active_vs_replica_struct {
5508         const char *line; /* just better debugging */
5509         struct nbt_name name;
5510         struct {
5511                 uint32_t nb_flags;
5512                 BOOL mhomed;
5513                 uint32_t num_ips;
5514                 const struct wrepl_ip *ips;
5515                 BOOL apply_expected;
5516         } wins;
5517         struct {
5518                 uint32_t timeout;
5519                 BOOL positive;
5520         } defend;
5521         struct {
5522                 enum wrepl_name_type type;
5523                 enum wrepl_name_state state;
5524                 enum wrepl_name_node node;
5525                 BOOL is_static;
5526                 uint32_t num_ips;
5527                 const struct wrepl_ip *ips;
5528                 BOOL apply_expected;
5529         } replica;
5530 };
5531
5532 static void test_conflict_owned_active_vs_replica_handler(struct nbt_name_socket *nbtsock, 
5533                                                           struct nbt_name_packet *req_packet, 
5534                                                           const struct nbt_peer_socket *src);
5535
5536 static BOOL test_conflict_owned_active_vs_replica(struct test_wrepl_conflict_conn *ctx)
5537 {
5538         BOOL ret = True;
5539         NTSTATUS status;
5540         struct wrepl_wins_name wins_name_;
5541         struct wrepl_wins_name *wins_name = &wins_name_;
5542         struct nbt_name_register name_register_;
5543         struct nbt_name_register *name_register = &name_register_;
5544         struct nbt_name_release release_;
5545         struct nbt_name_release *release = &release_;
5546         uint32_t i;
5547         struct test_conflict_owned_active_vs_replica_struct records[] = {
5548 /* 
5549  * unique vs. unique section
5550  */
5551         /*
5552          * unique,active vs. unique,active with same ip(s), unchecked
5553          */
5554         {
5555                 .line   = __location__,
5556                 .name   = _NBT_NAME("_UA_UA_SI_U", 0x00, NULL),
5557                 .wins   = {
5558                         .nb_flags       = 0,
5559                         .mhomed         = False,
5560                         .num_ips        = ctx->addresses_1_num,
5561                         .ips            = ctx->addresses_1,
5562                         .apply_expected = True
5563                 },
5564                 .defend = {
5565                         .timeout        = 0,
5566                 },
5567                 .replica= {
5568                         .type           = WREPL_TYPE_UNIQUE,
5569                         .state          = WREPL_STATE_ACTIVE,
5570                         .node           = WREPL_NODE_B,
5571                         .is_static      = False,
5572                         .num_ips        = ctx->addresses_1_num,
5573                         .ips            = ctx->addresses_1,
5574                         .apply_expected = True
5575                 },
5576         },
5577         /*
5578          * unique,active vs. unique,active with different ip(s), positive response
5579          */
5580         {
5581                 .line   = __location__,
5582                 .name   = _NBT_NAME("_UA_UA_DI_P", 0x00, NULL),
5583                 .wins   = {
5584                         .nb_flags       = 0,
5585                         .mhomed         = False,
5586                         .num_ips        = ctx->addresses_1_num,
5587                         .ips            = ctx->addresses_1,
5588                         .apply_expected = True
5589                 },
5590                 .defend = {
5591                         .timeout        = 10,
5592                         .positive       = True,
5593                 },
5594                 .replica= {
5595                         .type           = WREPL_TYPE_UNIQUE,
5596                         .state          = WREPL_STATE_ACTIVE,
5597                         .node           = WREPL_NODE_B,
5598                         .is_static      = False,
5599                         .num_ips        = ARRAY_SIZE(addresses_B_1),
5600                         .ips            = addresses_B_1,
5601                         .apply_expected = False
5602                 },
5603         },
5604         /*
5605          * unique,active vs. unique,active with different ip(s), negative response
5606          */
5607         {
5608                 .line   = __location__,
5609                 .name   = _NBT_NAME("_UA_UA_DI_N", 0x00, NULL),
5610                 .wins   = {
5611                         .nb_flags       = 0,
5612                         .mhomed         = False,
5613                         .num_ips        = ctx->addresses_1_num,
5614                         .ips            = ctx->addresses_1,
5615                         .apply_expected = True
5616                 },
5617                 .defend = {
5618                         .timeout        = 10,
5619                         .positive       = False,
5620                 },
5621                 .replica= {
5622                         .type           = WREPL_TYPE_UNIQUE,
5623                         .state          = WREPL_STATE_ACTIVE,
5624                         .node           = WREPL_NODE_B,
5625                         .is_static      = False,
5626                         .num_ips        = ARRAY_SIZE(addresses_B_1),
5627                         .ips            = addresses_B_1,
5628                         .apply_expected = True
5629                 },
5630         },
5631         /*
5632          * unique,active vs. unique,tombstone with same ip(s), unchecked
5633          */
5634         {
5635                 .line   = __location__,
5636                 .name   = _NBT_NAME("_UA_UT_SI_U", 0x00, NULL),
5637                 .wins   = {
5638                         .nb_flags       = 0,
5639                         .mhomed         = False,
5640                         .num_ips        = ctx->addresses_1_num,
5641                         .ips            = ctx->addresses_1,
5642                         .apply_expected = True
5643                 },
5644                 .defend = {
5645                         .timeout        = 0,
5646                 },
5647                 .replica= {
5648                         .type           = WREPL_TYPE_UNIQUE,
5649                         .state          = WREPL_STATE_TOMBSTONE,
5650                         .node           = WREPL_NODE_B,
5651                         .is_static      = False,
5652                         .num_ips        = ctx->addresses_1_num,
5653                         .ips            = ctx->addresses_1,
5654                         .apply_expected = False
5655                 },
5656         },
5657         /*
5658          * unique,active vs. unique,tombstone with different ip(s), unchecked
5659          */
5660         {
5661                 .line   = __location__,
5662                 .name   = _NBT_NAME("_UA_UT_DI_U", 0x00, NULL),
5663                 .wins   = {
5664                         .nb_flags       = 0,
5665                         .mhomed         = False,
5666                         .num_ips        = ctx->addresses_1_num,
5667                         .ips            = ctx->addresses_1,
5668                         .apply_expected = True
5669                 },
5670                 .defend = {
5671                         .timeout        = 0,
5672                 },
5673                 .replica= {
5674                         .type           = WREPL_TYPE_UNIQUE,
5675                         .state          = WREPL_STATE_TOMBSTONE,
5676                         .node           = WREPL_NODE_B,
5677                         .is_static      = False,
5678                         .num_ips        = ARRAY_SIZE(addresses_B_1),
5679                         .ips            = addresses_B_1,
5680                         .apply_expected = False
5681                 },
5682         },
5683         };
5684
5685         if (!ctx) return False;
5686
5687         if (!ctx->nbtsock_srv) {
5688                 printf("SKIP: Test Replica records vs. owned active records: not bound to port[%d]\n",
5689                         lp_nbt_port());
5690                 return True;
5691         }
5692
5693         printf("Test Replica records vs. owned active records\n");
5694
5695         for(i=0; ret && i < ARRAY_SIZE(records); i++) {
5696                 struct timeval end;
5697
5698                 printf("%s => %s\n", nbt_name_string(ctx, &records[i].name),
5699                         (records[i].replica.apply_expected?"REPLACE":"NOT REPLACE"));
5700
5701                 /* Prepare for the current test */
5702                 nbt_set_incoming_handler(ctx->nbtsock_srv,
5703                                          test_conflict_owned_active_vs_replica_handler,
5704                                          &records[i]);
5705
5706                 /*
5707                  * Setup Register
5708                  */
5709                 name_register->in.name          = records[i].name;
5710                 name_register->in.dest_addr     = ctx->address;
5711                 name_register->in.address       = records[i].wins.ips[0].ip;
5712                 name_register->in.nb_flags      = records[i].wins.nb_flags;
5713                 name_register->in.register_demand= False;
5714                 name_register->in.broadcast     = False;
5715                 name_register->in.multi_homed   = records[i].wins.mhomed;
5716                 name_register->in.ttl           = 300000;
5717                 name_register->in.timeout       = 70;
5718                 name_register->in.retries       = 0;
5719
5720                 status = nbt_name_register(ctx->nbtsock, ctx, name_register);
5721                 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
5722                         printf("No response from %s for name register\n", ctx->address);
5723                         ret = False;
5724                 }
5725                 if (!NT_STATUS_IS_OK(status)) {
5726                         printf("Bad response from %s for name register - %s\n",
5727                                ctx->address, nt_errstr(status));
5728                         ret = False;
5729                 }
5730                 CHECK_VALUE(name_register->out.rcode, 0);
5731                 CHECK_VALUE_STRING(name_register->out.reply_from, ctx->address);
5732                 CHECK_VALUE(name_register->out.name.type, records[i].name.type);
5733                 CHECK_VALUE_STRING(name_register->out.name.name, records[i].name.name);
5734                 CHECK_VALUE_STRING(name_register->out.name.scope, records[i].name.scope);
5735                 CHECK_VALUE_STRING(name_register->out.reply_addr, records[i].wins.ips[0].ip);
5736
5737                 /*
5738                  * Setup Replica
5739                  */
5740                 wins_name->name         = &records[i].name;
5741                 wins_name->flags        = WREPL_NAME_FLAGS(records[i].replica.type,
5742                                                            records[i].replica.state,
5743                                                            records[i].replica.node,
5744                                                            records[i].replica.is_static);
5745                 wins_name->id           = ++ctx->b.max_version;
5746                 if (wins_name->flags & 2) {
5747                         wins_name->addresses.addresses.num_ips = records[i].replica.num_ips;
5748                         wins_name->addresses.addresses.ips     = discard_const(records[i].replica.ips);
5749                 } else {
5750                         wins_name->addresses.ip = records[i].replica.ips[0].ip;
5751                 }
5752                 wins_name->unknown      = "255.255.255.255";
5753
5754                 ret &= test_wrepl_update_one(ctx, &ctx->b, wins_name);
5755
5756                 /*
5757                  * wait for the name query, which is handled in
5758                  * test_conflict_owned_active_vs_replica_handler()
5759                  */
5760                 end = timeval_current_ofs(records[i].defend.timeout,0);
5761                 while (records[i].defend.timeout > 0) {
5762                         event_loop_once(ctx->nbtsock_srv->event_ctx);
5763                         if (timeval_expired(&end)) break;
5764                 }
5765
5766                 ret &= test_wrepl_is_applied(ctx, &ctx->b, wins_name,
5767                                              records[i].replica.apply_expected);
5768
5769                 if (records[i].replica.apply_expected) {
5770                         wins_name->name         = &records[i].name;
5771                         wins_name->flags        = WREPL_NAME_FLAGS(WREPL_TYPE_UNIQUE,
5772                                                                    WREPL_STATE_TOMBSTONE,
5773                                                                    WREPL_NODE_B, False);
5774                         wins_name->id           = ++ctx->b.max_version;
5775                         wins_name->addresses.ip = addresses_B_1[0].ip;
5776                         wins_name->unknown      = "255.255.255.255";
5777
5778                         ret &= test_wrepl_update_one(ctx, &ctx->b, wins_name);
5779                         ret &= test_wrepl_is_applied(ctx, &ctx->b, wins_name, True);
5780                 } else {
5781                         release->in.name        = records[i].name;
5782                         release->in.dest_addr   = ctx->address;
5783                         release->in.address     = records[i].wins.ips[0].ip;
5784                         release->in.nb_flags    = records[i].wins.nb_flags;
5785                         release->in.broadcast   = False;
5786                         release->in.timeout     = 30;
5787                         release->in.retries     = 0;
5788
5789                         status = nbt_name_release(ctx->nbtsock, ctx, release);
5790                         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
5791                                 printf("No response from %s for name release\n", ctx->address);
5792                                 return False;
5793                         }
5794                         if (!NT_STATUS_IS_OK(status)) {
5795                                 printf("Bad response from %s for name query - %s\n",
5796                                        ctx->address, nt_errstr(status));
5797                                 return False;
5798                         }
5799                         CHECK_VALUE(release->out.rcode, 0);
5800                 }
5801 done:
5802                 if (!ret) {
5803                         printf("conflict handled wrong or record[%u]: %s\n", i, records[i].line);
5804                         return ret;
5805                 }
5806         }
5807
5808         return ret;
5809 }
5810
5811 static void test_conflict_owned_active_vs_replica_handler(struct nbt_name_socket *nbtsock, 
5812                                                           struct nbt_name_packet *req_packet, 
5813                                                           const struct nbt_peer_socket *src)
5814 {
5815         struct nbt_name *name;
5816         struct nbt_name_packet *rep_packet;
5817         struct test_conflict_owned_active_vs_replica_struct *rec = nbtsock->incoming.private;
5818
5819         switch (req_packet->operation & NBT_OPCODE) {
5820         case NBT_OPCODE_QUERY:
5821                 break;
5822         default:
5823                 printf("%s: unexpected incoming packet\n", __location__);
5824                 return;
5825         }
5826
5827 #define _NBT_ASSERT(v, correct) do { \
5828         if ((v) != (correct)) { \
5829                 printf("(%s) Incorrect value %s=%d - should be %s (%d)\n", \
5830                        __location__, #v, v, #correct, correct); \
5831                 return; \
5832         } \
5833 } while (0)
5834
5835         _NBT_ASSERT(req_packet->qdcount, 1);
5836         _NBT_ASSERT(req_packet->questions[0].question_type, NBT_QTYPE_NETBIOS);
5837         _NBT_ASSERT(req_packet->questions[0].question_class, NBT_QCLASS_IP);
5838
5839         name = &req_packet->questions[0].name;
5840
5841 #define _NBT_ASSERT_STRING(v, correct) do { \
5842         if ( ((!v) && (correct)) || \
5843              ((v) && (!correct)) || \
5844              ((v) && (correct) && strcmp(v,correct) != 0)) { \
5845                 printf("(%s) Incorrect value %s=%s - should be %s\n", \
5846                        __location__, #v, v, correct); \
5847                 return; \
5848         } \
5849 } while (0)
5850
5851         _NBT_ASSERT(name->type, rec->name.type);
5852         _NBT_ASSERT_STRING(name->name, rec->name.name);
5853         _NBT_ASSERT_STRING(name->scope, rec->name.scope);
5854
5855         rep_packet = talloc_zero(nbtsock, struct nbt_name_packet);
5856         if (rep_packet == NULL) return;
5857
5858         rep_packet->name_trn_id = req_packet->name_trn_id;
5859         rep_packet->ancount     = 1;
5860
5861         rep_packet->answers     = talloc_array(rep_packet, struct nbt_res_rec, 1);
5862         if (rep_packet->answers == NULL) return;
5863
5864         rep_packet->answers[0].name      = *name;
5865         rep_packet->answers[0].rr_type   = NBT_QTYPE_NULL;
5866         rep_packet->answers[0].rr_class  = NBT_QCLASS_IP;
5867         rep_packet->answers[0].ttl       = 0;
5868
5869         if (rec->defend.positive) {
5870                 uint32_t i;
5871
5872                 /* send a positive reply */
5873                 rep_packet->operation   = 
5874                                         NBT_FLAG_REPLY | 
5875                                         NBT_OPCODE_QUERY | 
5876                                         NBT_FLAG_AUTHORITIVE |
5877                                         NBT_FLAG_RECURSION_DESIRED |
5878                                         NBT_FLAG_RECURSION_AVAIL;
5879
5880                 rep_packet->answers[0].rdata.netbios.length = rec->wins.num_ips*6;
5881                 rep_packet->answers[0].rdata.netbios.addresses = 
5882                         talloc_array(rep_packet->answers, struct nbt_rdata_address, rec->wins.num_ips);
5883                 if (rep_packet->answers[0].rdata.netbios.addresses == NULL) return;
5884
5885                 for (i=0; i < rec->wins.num_ips; i++) {
5886                         struct nbt_rdata_address *addr = 
5887                                 &rep_packet->answers[0].rdata.netbios.addresses[i];
5888                         addr->nb_flags  = rec->wins.nb_flags;
5889                         addr->ipaddr    = rec->wins.ips[i].ip;
5890                 }
5891                 DEBUG(2,("Sending positive name query reply for %s to %s:%d\n", 
5892                         nbt_name_string(rep_packet, name), src->addr, src->port));
5893         } else {
5894                 /* send a negative reply */
5895                 rep_packet->operation   =
5896                                         NBT_FLAG_REPLY | 
5897                                         NBT_OPCODE_QUERY | 
5898                                         NBT_FLAG_AUTHORITIVE |
5899                                         NBT_RCODE_NAM;
5900                 ZERO_STRUCT(rep_packet->answers[0].rdata);
5901
5902                 DEBUG(2,("Sending negative name query reply for %s to %s:%d\n", 
5903                         nbt_name_string(rep_packet, name), src->addr, src->port));
5904         }
5905
5906         nbt_name_reply_send(nbtsock, src, rep_packet);
5907         talloc_free(rep_packet);
5908
5909         /* make sure we push the reply to the wire */
5910         event_loop_once(nbtsock->event_ctx);
5911
5912         rec->defend.timeout = 0;
5913 }
5914
5915 /*
5916   test WINS replication operations
5917 */
5918 BOOL torture_nbt_winsreplication_quick(void)
5919 {
5920         const char *address;
5921         struct nbt_name name;
5922         TALLOC_CTX *mem_ctx = talloc_new(NULL);
5923         NTSTATUS status;
5924         BOOL ret = True;
5925
5926         make_nbt_name_server(&name, lp_parm_string(-1, "torture", "host"));
5927
5928         /* do an initial name resolution to find its IP */
5929         status = resolve_name(&name, mem_ctx, &address, NULL);
5930         if (!NT_STATUS_IS_OK(status)) {
5931                 printf("Failed to resolve %s - %s\n",
5932                        name.name, nt_errstr(status));
5933                 talloc_free(mem_ctx);
5934                 return False;
5935         }
5936
5937         ret &= test_assoc_ctx1(mem_ctx, address);
5938         ret &= test_assoc_ctx2(mem_ctx, address);
5939
5940         talloc_free(mem_ctx);
5941
5942         return ret;
5943 }
5944
5945 /*
5946   test WINS replication operations
5947 */
5948 BOOL torture_nbt_winsreplication(void)
5949 {
5950         const char *address;
5951         struct nbt_name name;
5952         TALLOC_CTX *mem_ctx = talloc_new(NULL);
5953         NTSTATUS status;
5954         BOOL ret = True;
5955         struct test_wrepl_conflict_conn *ctx;
5956
5957         make_nbt_name_server(&name, lp_parm_string(-1, "torture", "host"));
5958
5959         /* do an initial name resolution to find its IP */
5960         status = resolve_name(&name, mem_ctx, &address, NULL);
5961         if (!NT_STATUS_IS_OK(status)) {
5962                 printf("Failed to resolve %s - %s\n",
5963                        name.name, nt_errstr(status));
5964                 talloc_free(mem_ctx);
5965                 return False;
5966         }
5967
5968         ret &= test_assoc_ctx1(mem_ctx, address);
5969         ret &= test_assoc_ctx2(mem_ctx, address);
5970
5971         ret &= test_wins_replication(mem_ctx, address);
5972
5973         ctx = test_create_conflict_ctx(mem_ctx, address);
5974
5975         ret &= test_conflict_same_owner(ctx);
5976         ret &= test_conflict_different_owner(ctx);
5977         ret &= test_conflict_owned_released_vs_replica(ctx);
5978         ret &= test_conflict_owned_active_vs_replica(ctx);
5979
5980         talloc_free(mem_ctx);
5981
5982         return ret;
5983 }