wreplsrv: log a successful replication cycle at level 1
[kai/samba.git] / source4 / wrepl_server / wrepl_out_helpers.c
index 3b69b40fa07ec2d61db4b57689379a251fba954a..e1e3f38b12e5a1e0463d6a7a1c1496be9964234f 100644 (file)
@@ -7,7 +7,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -16,8 +16,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "lib/socket/socket.h"
 #include "smbd/service_task.h"
 #include "smbd/service_stream.h"
-#include "librpc/gen_ndr/ndr_winsrepl.h"
+#include "librpc/gen_ndr/winsrepl.h"
 #include "wrepl_server/wrepl_server.h"
-#include "wrepl_server/wrepl_out_helpers.h"
+#include "nbt_server/wins/winsdb.h"
 #include "libcli/composite/composite.h"
 #include "libcli/wrepl/winsrepl.h"
+#include "libcli/resolve/resolve.h"
+#include "param/param.h"
 
 enum wreplsrv_out_connect_stage {
        WREPLSRV_OUT_CONNECT_STAGE_WAIT_SOCKET,
@@ -139,7 +140,7 @@ static struct composite_context *wreplsrv_out_connect_send(struct wreplsrv_partn
        struct wreplsrv_service *service = partner->service;
        struct wreplsrv_out_connect_state *state = NULL;
        struct wreplsrv_out_connection **wreplconnp = &wreplconn;
-       BOOL cached_connection = False;
+       bool cached_connection = false;
 
        c = talloc_zero(partner, struct composite_context);
        if (!c) goto failed;
@@ -154,11 +155,11 @@ static struct composite_context *wreplsrv_out_connect_send(struct wreplsrv_partn
        c->private_data = state;
 
        if (type == WINSREPL_PARTNER_PUSH) {
-               cached_connection       = True;
+               cached_connection       = true;
                wreplconn               = partner->push.wreplconn;
                wreplconnp              = &partner->push.wreplconn;
        } else if (type == WINSREPL_PARTNER_PULL) {
-               cached_connection       = True;
+               cached_connection       = true;
                wreplconn               = partner->pull.wreplconn;
                wreplconnp              = &partner->pull.wreplconn;
        }
@@ -186,13 +187,13 @@ static struct composite_context *wreplsrv_out_connect_send(struct wreplsrv_partn
 
        wreplconn->service      = service;
        wreplconn->partner      = partner;
-       wreplconn->sock         = wrepl_socket_init(wreplconn, service->task->event_ctx);
+       wreplconn->sock         = wrepl_socket_init(wreplconn, service->task->event_ctx, lp_iconv_convenience(service->task->lp_ctx));
        if (!wreplconn->sock) goto failed;
 
        state->stage    = WREPLSRV_OUT_CONNECT_STAGE_WAIT_SOCKET;
        state->wreplconn= wreplconn;
        state->c_req    = wrepl_connect_send(wreplconn->sock,
-                                            partner->our_address,
+                                            partner->our_address?partner->our_address:wrepl_best_ip(service->task->lp_ctx, partner->address),
                                             partner->address);
        if (!state->c_req) goto failed;
 
@@ -228,6 +229,18 @@ static NTSTATUS wreplsrv_out_connect_recv(struct composite_context *c, TALLOC_CT
        
 }
 
+struct wreplsrv_pull_table_io {
+       struct {
+               struct wreplsrv_partner *partner;
+               uint32_t num_owners;
+               struct wrepl_wins_owner *owners;
+       } in;
+       struct {
+               uint32_t num_owners;
+               struct wrepl_wins_owner *owners;
+       } out;
+};
+
 enum wreplsrv_pull_table_stage {
        WREPLSRV_PULL_TABLE_STAGE_WAIT_CONNECTION,
        WREPLSRV_PULL_TABLE_STAGE_WAIT_TABLE_REPLY,
@@ -318,7 +331,7 @@ static void wreplsrv_pull_table_handler_req(struct wrepl_request *req)
        return;
 }
 
-struct composite_context *wreplsrv_pull_table_send(TALLOC_CTX *mem_ctx, struct wreplsrv_pull_table_io *io)
+static struct composite_context *wreplsrv_pull_table_send(TALLOC_CTX *mem_ctx, struct wreplsrv_pull_table_io *io)
 {
        struct composite_context *c = NULL;
        struct wreplsrv_service *service = io->in.partner->service;
@@ -357,8 +370,8 @@ failed:
        return NULL;
 }
 
-NTSTATUS wreplsrv_pull_table_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
-                                 struct wreplsrv_pull_table_io *io)
+static NTSTATUS wreplsrv_pull_table_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
+                                        struct wreplsrv_pull_table_io *io)
 {
        NTSTATUS status;
 
@@ -368,14 +381,25 @@ NTSTATUS wreplsrv_pull_table_recv(struct composite_context *c, TALLOC_CTX *mem_c
                struct wreplsrv_pull_table_state *state = talloc_get_type(c->private_data,
                                                          struct wreplsrv_pull_table_state);
                io->out.num_owners      = state->table_io.out.num_partners;
-               io->out.owners          = state->table_io.out.partners;
-               talloc_reference(mem_ctx, state->table_io.out.partners);
+               io->out.owners          = talloc_reference(mem_ctx, state->table_io.out.partners);
        }
 
        talloc_free(c);
        return status;  
 }
 
+struct wreplsrv_pull_names_io {
+       struct {
+               struct wreplsrv_partner *partner;
+               struct wreplsrv_out_connection *wreplconn;
+               struct wrepl_wins_owner owner;
+       } in;
+       struct {
+               uint32_t num_names;
+               struct wrepl_name *names;
+       } out;
+};
+
 enum wreplsrv_pull_names_stage {
        WREPLSRV_PULL_NAMES_STAGE_WAIT_CONNECTION,
        WREPLSRV_PULL_NAMES_STAGE_WAIT_SEND_REPLY,
@@ -467,7 +491,7 @@ static void wreplsrv_pull_names_handler_req(struct wrepl_request *req)
        return;
 }
 
-struct composite_context *wreplsrv_pull_names_send(TALLOC_CTX *mem_ctx, struct wreplsrv_pull_names_io *io)
+static struct composite_context *wreplsrv_pull_names_send(TALLOC_CTX *mem_ctx, struct wreplsrv_pull_names_io *io)
 {
        struct composite_context *c = NULL;
        struct wreplsrv_service *service = io->in.partner->service;
@@ -501,8 +525,8 @@ failed:
        return NULL;
 }
 
-NTSTATUS wreplsrv_pull_names_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
-                                 struct wreplsrv_pull_names_io *io)
+static NTSTATUS wreplsrv_pull_names_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
+                                        struct wreplsrv_pull_names_io *io)
 {
        NTSTATUS status;
 
@@ -512,8 +536,7 @@ NTSTATUS wreplsrv_pull_names_recv(struct composite_context *c, TALLOC_CTX *mem_c
                struct wreplsrv_pull_names_state *state = talloc_get_type(c->private_data,
                                                          struct wreplsrv_pull_names_state);
                io->out.num_names       = state->pull_io.out.num_names;
-               io->out.names           = state->pull_io.out.names;
-               talloc_reference(mem_ctx, state->pull_io.out.names);
+               io->out.names           = talloc_reference(mem_ctx, state->pull_io.out.names);
        }
 
        talloc_free(c);
@@ -545,17 +568,19 @@ static void wreplsrv_pull_cycle_handler_req(struct wrepl_request *req);
 
 static NTSTATUS wreplsrv_pull_cycle_next_owner_do_work(struct wreplsrv_pull_cycle_state *state)
 {
-       struct wreplsrv_owner *current_owner;
+       struct wreplsrv_owner *current_owner=NULL;
        struct wreplsrv_owner *local_owner;
        uint32_t i;
        uint64_t old_max_version = 0;
-       BOOL do_pull = False;
+       bool do_pull = false;
 
        for (i=state->current; i < state->table_io.out.num_owners; i++) {
-               current_owner = wreplsrv_find_owner(state->io->in.partner->pull.table,
+               current_owner = wreplsrv_find_owner(state->io->in.partner->service,
+                                                   state->io->in.partner->pull.table,
                                                    state->table_io.out.owners[i].address);
 
-               local_owner = wreplsrv_find_owner(state->io->in.partner->service->table,
+               local_owner = wreplsrv_find_owner(state->io->in.partner->service,
+                                                 state->io->in.partner->service->table,
                                                  state->table_io.out.owners[i].address);
                /*
                 * this means we are ourself the current owner,
@@ -568,7 +593,7 @@ static NTSTATUS wreplsrv_pull_cycle_next_owner_do_work(struct wreplsrv_pull_cycl
                 * so fetch them
                 */
                if (!local_owner) {
-                       do_pull         = True;
+                       do_pull         = true;
                        
                        break;
                }
@@ -578,7 +603,7 @@ static NTSTATUS wreplsrv_pull_cycle_next_owner_do_work(struct wreplsrv_pull_cycl
                 * fetch them
                 */
                if (current_owner->owner.max_version > local_owner->owner.max_version) {
-                       do_pull         = True;
+                       do_pull         = true;
                        old_max_version = local_owner->owner.max_version;
                        break;
                }
@@ -639,12 +664,6 @@ static NTSTATUS wreplsrv_pull_cycle_wait_table_reply(struct wreplsrv_pull_cycle_
 
        /* update partner table */
        for (i=0; i < state->table_io.out.num_owners; i++) {
-               BOOL is_our_addr;
-
-               is_our_addr = wreplsrv_is_our_address(state->io->in.partner->service,
-                                                     state->table_io.out.owners[i].address);
-               if (is_our_addr) continue;
-
                status = wreplsrv_add_table(state->io->in.partner->service,
                                            state->io->in.partner, 
                                            &state->io->in.partner->pull.table,
@@ -663,7 +682,10 @@ static NTSTATUS wreplsrv_pull_cycle_apply_records(struct wreplsrv_pull_cycle_sta
 {
        NTSTATUS status;
 
-       status = wreplsrv_apply_records(state->io->in.partner, &state->names_io);
+       status = wreplsrv_apply_records(state->io->in.partner,
+                                       &state->names_io.in.owner,
+                                       state->names_io.out.num_names,
+                                       state->names_io.out.names);
        NT_STATUS_NOT_OK_RETURN(status);
 
        talloc_free(state->names_io.out.names);
@@ -807,7 +829,7 @@ struct wreplsrv_push_notify_state {
        struct composite_context *c;
        struct wreplsrv_push_notify_io *io;
        enum wrepl_replication_cmd command;
-       BOOL full_table;
+       bool full_table;
        struct wrepl_send_ctrl ctrl;
        struct wrepl_request *req;
        struct wrepl_packet req_packet;
@@ -830,7 +852,6 @@ static NTSTATUS wreplsrv_push_notify_update(struct wreplsrv_push_notify_state *s
        struct socket_context *sock;
        struct packet_context *packet;
        uint16_t fde_flags;
-       const char *our_ip;
 
        /* prepare the outgoing request */
        req->opcode     = WREPL_OPCODE_BITS;
@@ -839,11 +860,8 @@ static NTSTATUS wreplsrv_push_notify_update(struct wreplsrv_push_notify_state *s
 
        repl_out->command = state->command;
 
-       our_ip = socket_get_my_addr(state->wreplconn->sock->sock, state);
-       NT_STATUS_HAVE_NO_MEMORY(our_ip);
-
        status = wreplsrv_fill_wrepl_table(service, state, table_out,
-                                          our_ip, our_ip, state->full_table);
+                                          service->wins_db->local_owner, state->full_table);
        NT_STATUS_NOT_OK_RETURN(status);
 
        /* queue the request */
@@ -916,7 +934,6 @@ static NTSTATUS wreplsrv_push_notify_inform(struct wreplsrv_push_notify_state *s
        struct wrepl_replication *repl_out = &state->req_packet.message.replication;
        struct wrepl_table *table_out = &state->req_packet.message.replication.info.table;
        NTSTATUS status;
-       const char *our_ip;
 
        req->opcode     = WREPL_OPCODE_BITS;
        req->assoc_ctx  = state->wreplconn->assoc_ctx.peer_ctx;
@@ -924,15 +941,12 @@ static NTSTATUS wreplsrv_push_notify_inform(struct wreplsrv_push_notify_state *s
 
        repl_out->command = state->command;
 
-       our_ip = socket_get_my_addr(state->wreplconn->sock->sock, state);
-       NT_STATUS_HAVE_NO_MEMORY(our_ip);
-
        status = wreplsrv_fill_wrepl_table(service, state, table_out,
-                                          our_ip, our_ip, state->full_table);
+                                          service->wins_db->local_owner, state->full_table);
        NT_STATUS_NOT_OK_RETURN(status);
 
        /* we won't get a reply to a inform message */
-       state->ctrl.send_only           = True;
+       state->ctrl.send_only           = true;
 
        state->req = wrepl_request_send(state->wreplconn->sock, req, &state->ctrl);
        NT_STATUS_HAVE_NO_MEMORY(state->req);
@@ -954,16 +968,16 @@ static NTSTATUS wreplsrv_push_notify_wait_connect(struct wreplsrv_push_notify_st
 
        switch (state->command) {
        case WREPL_REPL_UPDATE:
-               state->full_table = True;
+               state->full_table = true;
                return wreplsrv_push_notify_update(state);
        case WREPL_REPL_UPDATE2:
-               state->full_table = False;
+               state->full_table = false;
                return wreplsrv_push_notify_update(state);
        case WREPL_REPL_INFORM:
-               state->full_table = True;
+               state->full_table = true;
                return wreplsrv_push_notify_inform(state);
        case WREPL_REPL_INFORM2:
-               state->full_table = False;
+               state->full_table = false;
                return wreplsrv_push_notify_inform(state);
        default:
                return NT_STATUS_INTERNAL_ERROR;