Merge branch 'master' of ssh://git.samba.org/data/git/samba
[ira/wip.git] / source4 / wrepl_server / wrepl_out_helpers.c
index 72d55985bbcaeb835cbda736b7f8b468d9f03fa3..6aff1340720393115c4e2da2a2aa17ffae0df7b3 100644 (file)
@@ -62,7 +62,7 @@ static NTSTATUS wreplsrv_out_connect_wait_socket(struct wreplsrv_out_connect_sta
        NT_STATUS_HAVE_NO_MEMORY(state->req);
 
        state->req->async.fn            = wreplsrv_out_connect_handler_req;
-       state->req->async.private       = state;
+       state->req->async.private_data  = state;
 
        state->stage = WREPLSRV_OUT_CONNECT_STAGE_WAIT_ASSOC_CTX;
 
@@ -77,10 +77,15 @@ static NTSTATUS wreplsrv_out_connect_wait_assoc_ctx(struct wreplsrv_out_connect_
        NT_STATUS_NOT_OK_RETURN(status);
 
        state->wreplconn->assoc_ctx.peer_ctx = state->assoc_io.out.assoc_ctx;
+       state->wreplconn->assoc_ctx.peer_major = state->assoc_io.out.major_version;
 
        if (state->type == WINSREPL_PARTNER_PUSH) {
-               state->wreplconn->partner->push.wreplconn = state->wreplconn;
-               talloc_steal(state->wreplconn->partner, state->wreplconn);
+               if (state->wreplconn->assoc_ctx.peer_major >= 5) {
+                       state->wreplconn->partner->push.wreplconn = state->wreplconn;
+                       talloc_steal(state->wreplconn->partner, state->wreplconn);
+               } else {
+                       state->type = WINSREPL_PARTNER_NONE;
+               }
        } else if (state->type == WINSREPL_PARTNER_PULL) {
                state->wreplconn->partner->pull.wreplconn = state->wreplconn;
                talloc_steal(state->wreplconn->partner, state->wreplconn);
@@ -126,7 +131,7 @@ static void wreplsrv_out_connect_handler_creq(struct composite_context *creq)
 
 static void wreplsrv_out_connect_handler_req(struct wrepl_request *req)
 {
-       struct wreplsrv_out_connect_state *state = talloc_get_type(req->async.private,
+       struct wreplsrv_out_connect_state *state = talloc_get_type(req->async.private_data,
                                                   struct wreplsrv_out_connect_state);
        wreplsrv_out_connect_handler(state);
        return;
@@ -193,8 +198,7 @@ static struct composite_context *wreplsrv_out_connect_send(struct wreplsrv_partn
        state->stage    = WREPLSRV_OUT_CONNECT_STAGE_WAIT_SOCKET;
        state->wreplconn= wreplconn;
        state->c_req    = wrepl_connect_send(wreplconn->sock,
-                                            lp_resolve_context(service->task->lp_ctx),
-                                            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;
 
@@ -272,7 +276,7 @@ static NTSTATUS wreplsrv_pull_table_wait_connection(struct wreplsrv_pull_table_s
        NT_STATUS_HAVE_NO_MEMORY(state->req);
 
        state->req->async.fn            = wreplsrv_pull_table_handler_req;
-       state->req->async.private       = state;
+       state->req->async.private_data  = state;
 
        state->stage = WREPLSRV_PULL_TABLE_STAGE_WAIT_TABLE_REPLY;
 
@@ -326,7 +330,7 @@ static void wreplsrv_pull_table_handler_creq(struct composite_context *creq)
 
 static void wreplsrv_pull_table_handler_req(struct wrepl_request *req)
 {
-       struct wreplsrv_pull_table_state *state = talloc_get_type(req->async.private,
+       struct wreplsrv_pull_table_state *state = talloc_get_type(req->async.private_data,
                                                  struct wreplsrv_pull_table_state);
        wreplsrv_pull_table_handler(state);
        return;
@@ -432,7 +436,7 @@ static NTSTATUS wreplsrv_pull_names_wait_connection(struct wreplsrv_pull_names_s
        NT_STATUS_HAVE_NO_MEMORY(state->req);
 
        state->req->async.fn            = wreplsrv_pull_names_handler_req;
-       state->req->async.private       = state;
+       state->req->async.private_data  = state;
 
        state->stage = WREPLSRV_PULL_NAMES_STAGE_WAIT_SEND_REPLY;
 
@@ -486,7 +490,7 @@ static void wreplsrv_pull_names_handler_creq(struct composite_context *creq)
 
 static void wreplsrv_pull_names_handler_req(struct wrepl_request *req)
 {
-       struct wreplsrv_pull_names_state *state = talloc_get_type(req->async.private,
+       struct wreplsrv_pull_names_state *state = talloc_get_type(req->async.private_data,
                                                  struct wreplsrv_pull_names_state);
        wreplsrv_pull_names_handler(state);
        return;
@@ -647,7 +651,7 @@ static NTSTATUS wreplsrv_pull_cycle_next_owner_wrapper(struct wreplsrv_pull_cycl
                NT_STATUS_HAVE_NO_MEMORY(state->req);
 
                state->req->async.fn            = wreplsrv_pull_cycle_handler_req;
-               state->req->async.private       = state;
+               state->req->async.private_data  = state;
 
                state->stage = WREPLSRV_PULL_CYCLE_STAGE_WAIT_STOP_ASSOC;
        }
@@ -769,7 +773,7 @@ static void wreplsrv_pull_cycle_handler_creq(struct composite_context *creq)
 
 static void wreplsrv_pull_cycle_handler_req(struct wrepl_request *req)
 {
-       struct wreplsrv_pull_cycle_state *state = talloc_get_type(req->async.private,
+       struct wreplsrv_pull_cycle_state *state = talloc_get_type(req->async.private_data,
                                                  struct wreplsrv_pull_cycle_state);
        wreplsrv_pull_cycle_handler(state);
        return;
@@ -953,7 +957,7 @@ static NTSTATUS wreplsrv_push_notify_inform(struct wreplsrv_push_notify_state *s
        NT_STATUS_HAVE_NO_MEMORY(state->req);
 
        state->req->async.fn            = wreplsrv_push_notify_handler_req;
-       state->req->async.private       = state;
+       state->req->async.private_data  = state;
 
        state->stage = WREPLSRV_PUSH_NOTIFY_STAGE_WAIT_INFORM;
 
@@ -967,6 +971,22 @@ static NTSTATUS wreplsrv_push_notify_wait_connect(struct wreplsrv_push_notify_st
        status = wreplsrv_out_connect_recv(state->creq, state, &state->wreplconn);
        NT_STATUS_NOT_OK_RETURN(status);
 
+       /* is the peer doesn't support inform fallback to update */
+       switch (state->command) {
+       case WREPL_REPL_INFORM:
+               if (state->wreplconn->assoc_ctx.peer_major < 5) {
+                       state->command = WREPL_REPL_UPDATE;
+               }
+               break;
+       case WREPL_REPL_INFORM2:
+               if (state->wreplconn->assoc_ctx.peer_major < 5) {
+                       state->command = WREPL_REPL_UPDATE2;
+               }
+               break;
+       default:
+               break;
+       }
+
        switch (state->command) {
        case WREPL_REPL_UPDATE:
                state->full_table = true;
@@ -1036,7 +1056,7 @@ static void wreplsrv_push_notify_handler_creq(struct composite_context *creq)
 
 static void wreplsrv_push_notify_handler_req(struct wrepl_request *req)
 {
-       struct wreplsrv_push_notify_state *state = talloc_get_type(req->async.private,
+       struct wreplsrv_push_notify_state *state = talloc_get_type(req->async.private_data,
                                                   struct wreplsrv_push_notify_state);
        wreplsrv_push_notify_handler(state);
        return;