wrepl_server: make 'use inform' the default and autofallback against old servers
[kai/samba.git] / source4 / wrepl_server / wrepl_out_push.c
index 6ac04d9f126955eebc8340e7e04018f528717b1e..8f0c409662e42abfcbc2028027cd72fff8351e80 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,
    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 "librpc/gen_ndr/ndr_winsrepl.h"
+#include "librpc/gen_ndr/winsrepl.h"
 #include "wrepl_server/wrepl_server.h"
 #include "libcli/composite/composite.h"
-#include "wrepl_server/wrepl_out_helpers.h"
+#include "nbt_server/wins/winsdb.h"
 
-static void wreplsrv_out_partner_push(struct wreplsrv_partner *partner, BOOL propagate);
+static void wreplsrv_out_partner_push(struct wreplsrv_partner *partner, bool propagate);
 
 static void wreplsrv_push_handler_creq(struct composite_context *creq)
 {
@@ -63,7 +62,7 @@ done:
        talloc_free(old_notify_io);
 }
 
-static void wreplsrv_out_partner_push(struct wreplsrv_partner *partner, BOOL propagate)
+static void wreplsrv_out_partner_push(struct wreplsrv_partner *partner, bool propagate)
 {
        /* a push for this partner is currently in progress, so we're done */
        if (partner->push.creq) return;
@@ -96,17 +95,35 @@ nomem:
        return;
 }
 
-static uint32_t wreplsrv_calc_change_count(struct wreplsrv_partner *partner)
+static uint32_t wreplsrv_calc_change_count(struct wreplsrv_partner *partner, uint64_t maxVersionID)
 {
-       /* TODO: add a real implementation here */
-       return (uint32_t)-1;
+       uint64_t tmp_diff = UINT32_MAX;
+
+       /* catch an overflow */
+       if (partner->push.maxVersionID > maxVersionID) {
+               goto done;
+       }
+
+       tmp_diff = maxVersionID - partner->push.maxVersionID;
+
+       if (tmp_diff > UINT32_MAX) {
+               tmp_diff = UINT32_MAX;
+               goto done;
+       }
+
+done:
+       partner->push.maxVersionID = maxVersionID;
+       return (uint32_t)(tmp_diff & UINT32_MAX);
 }
 
 NTSTATUS wreplsrv_out_push_run(struct wreplsrv_service *service)
 {
        struct wreplsrv_partner *partner;
+       uint64_t seqnumber;
        uint32_t change_count;
 
+       seqnumber = winsdb_get_maxVersion(service->wins_db);
+
        for (partner = service->partners; partner; partner = partner->next) {
                /* if it's not a push partner, go to the next partner */
                if (!(partner->type & WINSREPL_PARTNER_PUSH)) continue;
@@ -115,12 +132,12 @@ NTSTATUS wreplsrv_out_push_run(struct wreplsrv_service *service)
                if (partner->push.change_count == 0) continue;
 
                /* get the actual change count for the partner */
-               change_count = wreplsrv_calc_change_count(partner);
+               change_count = wreplsrv_calc_change_count(partner, seqnumber);
 
                /* if the configured change count isn't reached, go to the next partner */
                if (change_count < partner->push.change_count) continue;
 
-               wreplsrv_out_partner_push(partner, False);
+               wreplsrv_out_partner_push(partner, false);
        }
 
        return NT_STATUS_OK;