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 "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,
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;
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;
}
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;
}
+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,
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;
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;
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,
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;
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;
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);
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,
* so fetch them
*/
if (!local_owner) {
- do_pull = True;
+ do_pull = true;
break;
}
* 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;
}
/* 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,
{
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);
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;
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;
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 */
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;
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);
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;