⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wrepl_out_helpers.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
/*    Unix SMB/CIFS implementation.      WINS Replication server      Copyright (C) Stefan Metzmacher	2005      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 3 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   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, see <http://www.gnu.org/licenses/>.*/#include "includes.h"#include "lib/events/events.h"#include "lib/socket/socket.h"#include "smbd/service_task.h"#include "smbd/service_stream.h"#include "librpc/gen_ndr/winsrepl.h"#include "wrepl_server/wrepl_server.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,	WREPLSRV_OUT_CONNECT_STAGE_WAIT_ASSOC_CTX,	WREPLSRV_OUT_CONNECT_STAGE_DONE};struct wreplsrv_out_connect_state {	enum wreplsrv_out_connect_stage stage;	struct composite_context *c;	struct wrepl_request *req;	struct composite_context *c_req;	struct wrepl_associate assoc_io;	enum winsrepl_partner_type type;	struct wreplsrv_out_connection *wreplconn;};static void wreplsrv_out_connect_handler_creq(struct composite_context *c_req);static void wreplsrv_out_connect_handler_req(struct wrepl_request *req);static NTSTATUS wreplsrv_out_connect_wait_socket(struct wreplsrv_out_connect_state *state){	NTSTATUS status;	status = wrepl_connect_recv(state->c_req);	NT_STATUS_NOT_OK_RETURN(status);	state->req = wrepl_associate_send(state->wreplconn->sock, &state->assoc_io);	NT_STATUS_HAVE_NO_MEMORY(state->req);	state->req->async.fn		= wreplsrv_out_connect_handler_req;	state->req->async.private	= state;	state->stage = WREPLSRV_OUT_CONNECT_STAGE_WAIT_ASSOC_CTX;	return NT_STATUS_OK;}static NTSTATUS wreplsrv_out_connect_wait_assoc_ctx(struct wreplsrv_out_connect_state *state){	NTSTATUS status;	status = wrepl_associate_recv(state->req, &state->assoc_io);	NT_STATUS_NOT_OK_RETURN(status);	state->wreplconn->assoc_ctx.peer_ctx = state->assoc_io.out.assoc_ctx;	if (state->type == WINSREPL_PARTNER_PUSH) {		state->wreplconn->partner->push.wreplconn = state->wreplconn;		talloc_steal(state->wreplconn->partner, state->wreplconn);	} else if (state->type == WINSREPL_PARTNER_PULL) {		state->wreplconn->partner->pull.wreplconn = state->wreplconn;		talloc_steal(state->wreplconn->partner, state->wreplconn);	}	state->stage = WREPLSRV_OUT_CONNECT_STAGE_DONE;	return NT_STATUS_OK;}static void wreplsrv_out_connect_handler(struct wreplsrv_out_connect_state *state){	struct composite_context *c = state->c;	switch (state->stage) {	case WREPLSRV_OUT_CONNECT_STAGE_WAIT_SOCKET:		c->status = wreplsrv_out_connect_wait_socket(state);		break;	case WREPLSRV_OUT_CONNECT_STAGE_WAIT_ASSOC_CTX:		c->status = wreplsrv_out_connect_wait_assoc_ctx(state);		c->state  = COMPOSITE_STATE_DONE;		break;	case WREPLSRV_OUT_CONNECT_STAGE_DONE:		c->status = NT_STATUS_INTERNAL_ERROR;	}	if (!NT_STATUS_IS_OK(c->status)) {		c->state = COMPOSITE_STATE_ERROR;	}	if (c->state >= COMPOSITE_STATE_DONE && c->async.fn) {		c->async.fn(c);	}}static void wreplsrv_out_connect_handler_creq(struct composite_context *creq){	struct wreplsrv_out_connect_state *state = talloc_get_type(creq->async.private_data,						   struct wreplsrv_out_connect_state);	wreplsrv_out_connect_handler(state);	return;}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);	wreplsrv_out_connect_handler(state);	return;}static struct composite_context *wreplsrv_out_connect_send(struct wreplsrv_partner *partner,							   enum winsrepl_partner_type type,							   struct wreplsrv_out_connection *wreplconn){	struct composite_context *c = NULL;	struct wreplsrv_service *service = partner->service;	struct wreplsrv_out_connect_state *state = NULL;	struct wreplsrv_out_connection **wreplconnp = &wreplconn;	bool cached_connection = false;	c = talloc_zero(partner, struct composite_context);	if (!c) goto failed;	state = talloc_zero(c, struct wreplsrv_out_connect_state);	if (!state) goto failed;	state->c	= c;	state->type	= type;	c->state	= COMPOSITE_STATE_IN_PROGRESS;	c->event_ctx	= service->task->event_ctx;	c->private_data	= state;	if (type == WINSREPL_PARTNER_PUSH) {		cached_connection	= true;		wreplconn		= partner->push.wreplconn;		wreplconnp		= &partner->push.wreplconn;	} else if (type == WINSREPL_PARTNER_PULL) {		cached_connection	= true;		wreplconn		= partner->pull.wreplconn;		wreplconnp		= &partner->pull.wreplconn;	}	/* we have a connection already, so use it */	if (wreplconn) {		if (!wreplconn->sock->dead) {			state->stage	= WREPLSRV_OUT_CONNECT_STAGE_DONE;			state->wreplconn= wreplconn;			composite_done(c);			return c;		} else if (!cached_connection) {			state->stage	= WREPLSRV_OUT_CONNECT_STAGE_DONE;			state->wreplconn= NULL;			composite_done(c);			return c;		} else {			talloc_free(wreplconn);			*wreplconnp = NULL;		}	}	wreplconn = talloc_zero(state, struct wreplsrv_out_connection);	if (!wreplconn) goto failed;	wreplconn->service	= service;	wreplconn->partner	= partner;	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,					     lp_resolve_context(service->task->lp_ctx),					     partner->our_address?partner->our_address:wrepl_best_ip(service->task->lp_ctx, partner->address),					     partner->address);	if (!state->c_req) goto failed;	state->c_req->async.fn			= wreplsrv_out_connect_handler_creq;	state->c_req->async.private_data	= state;	return c;failed:	talloc_free(c);	return NULL;}static NTSTATUS wreplsrv_out_connect_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,					  struct wreplsrv_out_connection **wreplconn){	NTSTATUS status;	status = composite_wait(c);	if (NT_STATUS_IS_OK(status)) {		struct wreplsrv_out_connect_state *state = talloc_get_type(c->private_data,							   struct wreplsrv_out_connect_state);		if (state->wreplconn) {			*wreplconn = talloc_reference(mem_ctx, state->wreplconn);			if (!*wreplconn) status = NT_STATUS_NO_MEMORY;		} else {			status = NT_STATUS_INVALID_CONNECTION;		}	}	talloc_free(c);	return status;	}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,	WREPLSRV_PULL_TABLE_STAGE_DONE};struct wreplsrv_pull_table_state {	enum wreplsrv_pull_table_stage stage;	struct composite_context *c;	struct wrepl_request *req;	struct wrepl_pull_table table_io;	struct wreplsrv_pull_table_io *io;	struct composite_context *creq;	struct wreplsrv_out_connection *wreplconn;};static void wreplsrv_pull_table_handler_req(struct wrepl_request *req);static NTSTATUS wreplsrv_pull_table_wait_connection(struct wreplsrv_pull_table_state *state){	NTSTATUS status;	status = wreplsrv_out_connect_recv(state->creq, state, &state->wreplconn);	NT_STATUS_NOT_OK_RETURN(status);	state->table_io.in.assoc_ctx = state->wreplconn->assoc_ctx.peer_ctx;	state->req = wrepl_pull_table_send(state->wreplconn->sock, &state->table_io);	NT_STATUS_HAVE_NO_MEMORY(state->req);	state->req->async.fn		= wreplsrv_pull_table_handler_req;	state->req->async.private	= state;	state->stage = WREPLSRV_PULL_TABLE_STAGE_WAIT_TABLE_REPLY;	return NT_STATUS_OK;}static NTSTATUS wreplsrv_pull_table_wait_table_reply(struct wreplsrv_pull_table_state *state){	NTSTATUS status;	status = wrepl_pull_table_recv(state->req, state, &state->table_io);	NT_STATUS_NOT_OK_RETURN(status);	state->stage = WREPLSRV_PULL_TABLE_STAGE_DONE;	return NT_STATUS_OK;}static void wreplsrv_pull_table_handler(struct wreplsrv_pull_table_state *state){	struct composite_context *c = state->c;	switch (state->stage) {	case WREPLSRV_PULL_TABLE_STAGE_WAIT_CONNECTION:		c->status = wreplsrv_pull_table_wait_connection(state);		break;	case WREPLSRV_PULL_TABLE_STAGE_WAIT_TABLE_REPLY:		c->status = wreplsrv_pull_table_wait_table_reply(state);		c->state  = COMPOSITE_STATE_DONE;		break;	case WREPLSRV_PULL_TABLE_STAGE_DONE:		c->status = NT_STATUS_INTERNAL_ERROR;	}	if (!NT_STATUS_IS_OK(c->status)) {		c->state = COMPOSITE_STATE_ERROR;	}	if (c->state >= COMPOSITE_STATE_DONE && c->async.fn) {		c->async.fn(c);	}}static void wreplsrv_pull_table_handler_creq(struct composite_context *creq){	struct wreplsrv_pull_table_state *state = talloc_get_type(creq->async.private_data,						  struct wreplsrv_pull_table_state);	wreplsrv_pull_table_handler(state);	return;}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);	wreplsrv_pull_table_handler(state);	return;}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;	struct wreplsrv_pull_table_state *state = NULL;	c = talloc_zero(mem_ctx, struct composite_context);	if (!c) goto failed;	state = talloc_zero(c, struct wreplsrv_pull_table_state);	if (!state) goto failed;	state->c	= c;	state->io	= io;	c->state	= COMPOSITE_STATE_IN_PROGRESS;	c->event_ctx	= service->task->event_ctx;	c->private_data	= state;	if (io->in.num_owners) {		state->table_io.out.num_partners	= io->in.num_owners;		state->table_io.out.partners		= io->in.owners;		state->stage				= WREPLSRV_PULL_TABLE_STAGE_DONE;		composite_done(c);		return c;	}	state->stage    = WREPLSRV_PULL_TABLE_STAGE_WAIT_CONNECTION;	state->creq	= wreplsrv_out_connect_send(io->in.partner, WINSREPL_PARTNER_PULL, NULL);	if (!state->creq) goto failed;	state->creq->async.fn		= wreplsrv_pull_table_handler_creq;	state->creq->async.private_data	= state;	return c;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -