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

📄 wrepl_out_helpers.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
		c->status = wreplsrv_pull_cycle_wait_table_reply(state);		break;	case WREPLSRV_PULL_CYCLE_STAGE_WAIT_SEND_REPLIES:		c->status = wreplsrv_pull_cycle_wait_send_replies(state);		break;	case WREPLSRV_PULL_CYCLE_STAGE_WAIT_STOP_ASSOC:		c->status = wreplsrv_pull_cycle_wait_stop_assoc(state);		break;	case WREPLSRV_PULL_CYCLE_STAGE_DONE:		c->status = NT_STATUS_INTERNAL_ERROR;	}	if (state->stage == WREPLSRV_PULL_CYCLE_STAGE_DONE) {		c->state  = COMPOSITE_STATE_DONE;	}	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_cycle_handler_creq(struct composite_context *creq){	struct wreplsrv_pull_cycle_state *state = talloc_get_type(creq->async.private_data,						  struct wreplsrv_pull_cycle_state);	wreplsrv_pull_cycle_handler(state);	return;}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);	wreplsrv_pull_cycle_handler(state);	return;}struct composite_context *wreplsrv_pull_cycle_send(TALLOC_CTX *mem_ctx, struct wreplsrv_pull_cycle_io *io){	struct composite_context *c = NULL;	struct wreplsrv_service *service = io->in.partner->service;	struct wreplsrv_pull_cycle_state *state = NULL;	c = talloc_zero(mem_ctx, struct composite_context);	if (!c) goto failed;	state = talloc_zero(c, struct wreplsrv_pull_cycle_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;	state->stage	= WREPLSRV_PULL_CYCLE_STAGE_WAIT_TABLE_REPLY;	state->table_io.in.partner	= io->in.partner;	state->table_io.in.num_owners	= io->in.num_owners;	state->table_io.in.owners	= io->in.owners;	state->creq = wreplsrv_pull_table_send(state, &state->table_io);	if (!state->creq) goto failed;	state->creq->async.fn		= wreplsrv_pull_cycle_handler_creq;	state->creq->async.private_data	= state;	return c;failed:	talloc_free(c);	return NULL;}NTSTATUS wreplsrv_pull_cycle_recv(struct composite_context *c){	NTSTATUS status;	status = composite_wait(c);	talloc_free(c);	return status;}enum wreplsrv_push_notify_stage {	WREPLSRV_PUSH_NOTIFY_STAGE_WAIT_CONNECT,	WREPLSRV_PUSH_NOTIFY_STAGE_WAIT_INFORM,	WREPLSRV_PUSH_NOTIFY_STAGE_DONE};struct wreplsrv_push_notify_state {	enum wreplsrv_push_notify_stage stage;	struct composite_context *c;	struct wreplsrv_push_notify_io *io;	enum wrepl_replication_cmd command;	bool full_table;	struct wrepl_send_ctrl ctrl;	struct wrepl_request *req;	struct wrepl_packet req_packet;	struct wrepl_packet *rep_packet;	struct composite_context *creq;	struct wreplsrv_out_connection *wreplconn;};static void wreplsrv_push_notify_handler_creq(struct composite_context *creq);static void wreplsrv_push_notify_handler_req(struct wrepl_request *req);static NTSTATUS wreplsrv_push_notify_update(struct wreplsrv_push_notify_state *state){	struct wreplsrv_service *service = state->io->in.partner->service;	struct wrepl_packet *req = &state->req_packet;	struct wrepl_replication *repl_out = &state->req_packet.message.replication;	struct wrepl_table *table_out = &state->req_packet.message.replication.info.table;	struct wreplsrv_in_connection *wrepl_in;	NTSTATUS status;	struct socket_context *sock;	struct packet_context *packet;	uint16_t fde_flags;	/* prepare the outgoing request */	req->opcode	= WREPL_OPCODE_BITS;	req->assoc_ctx	= state->wreplconn->assoc_ctx.peer_ctx;	req->mess_type	= WREPL_REPLICATION;	repl_out->command = state->command;	status = wreplsrv_fill_wrepl_table(service, state, table_out,					   service->wins_db->local_owner, state->full_table);	NT_STATUS_NOT_OK_RETURN(status);	/* queue the request */	state->req = wrepl_request_send(state->wreplconn->sock, req, NULL);	NT_STATUS_HAVE_NO_MEMORY(state->req);	/*	 * now we need to convert the wrepl_socket (client connection)	 * into a wreplsrv_in_connection (server connection), because	 * we'll act as a server on this connection after the WREPL_REPL_UPDATE*	 * message is received by the peer.	 */	/* steal the socket_context */	sock = state->wreplconn->sock->sock;	state->wreplconn->sock->sock = NULL;	talloc_steal(state, sock);	/* 	 * steal the packet_context	 * note the request DATA_BLOB we just send on the	 * wrepl_socket (client connection) is still unter the 	 * packet context and will be send to the wire	 */	packet = state->wreplconn->sock->packet;	state->wreplconn->sock->packet = NULL;	talloc_steal(state, packet);	/*	 * get the fde_flags of the old fde event,	 * so that we can later set the same flags to the new one	 */	fde_flags = event_get_fd_flags(state->wreplconn->sock->event.fde);	/*	 * free the wrepl_socket (client connection)	 */	talloc_free(state->wreplconn->sock);	state->wreplconn->sock = NULL;	/*	 * now create a wreplsrv_in_connection,	 * on which we act as server	 *	 * NOTE: sock and packet will be stolen by	 *       wreplsrv_in_connection_merge()	 */	status = wreplsrv_in_connection_merge(state->io->in.partner,					      sock, packet, &wrepl_in);	NT_STATUS_NOT_OK_RETURN(status);	event_set_fd_flags(wrepl_in->conn->event.fde, fde_flags);	wrepl_in->assoc_ctx.peer_ctx	= state->wreplconn->assoc_ctx.peer_ctx;	wrepl_in->assoc_ctx.our_ctx	= 0;	/* now we can free the wreplsrv_out_connection */	talloc_free(state->wreplconn);	state->wreplconn = NULL;	state->stage = WREPLSRV_PUSH_NOTIFY_STAGE_DONE;	return NT_STATUS_OK;}static NTSTATUS wreplsrv_push_notify_inform(struct wreplsrv_push_notify_state *state){	struct wreplsrv_service *service = state->io->in.partner->service;	struct wrepl_packet *req = &state->req_packet;	struct wrepl_replication *repl_out = &state->req_packet.message.replication;	struct wrepl_table *table_out = &state->req_packet.message.replication.info.table;	NTSTATUS status;	req->opcode	= WREPL_OPCODE_BITS;	req->assoc_ctx	= state->wreplconn->assoc_ctx.peer_ctx;	req->mess_type	= WREPL_REPLICATION;	repl_out->command = state->command;	status = wreplsrv_fill_wrepl_table(service, state, table_out,					   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->req = wrepl_request_send(state->wreplconn->sock, req, &state->ctrl);	NT_STATUS_HAVE_NO_MEMORY(state->req);	state->req->async.fn		= wreplsrv_push_notify_handler_req;	state->req->async.private	= state;	state->stage = WREPLSRV_PUSH_NOTIFY_STAGE_WAIT_INFORM;	return NT_STATUS_OK;}static NTSTATUS wreplsrv_push_notify_wait_connect(struct wreplsrv_push_notify_state *state){	NTSTATUS status;	status = wreplsrv_out_connect_recv(state->creq, state, &state->wreplconn);	NT_STATUS_NOT_OK_RETURN(status);	switch (state->command) {	case WREPL_REPL_UPDATE:		state->full_table = true;		return wreplsrv_push_notify_update(state);	case WREPL_REPL_UPDATE2:		state->full_table = false;		return wreplsrv_push_notify_update(state);	case WREPL_REPL_INFORM:		state->full_table = true;		return wreplsrv_push_notify_inform(state);	case WREPL_REPL_INFORM2:		state->full_table = false;		return wreplsrv_push_notify_inform(state);	default:		return NT_STATUS_INTERNAL_ERROR;	}	return NT_STATUS_INTERNAL_ERROR;}static NTSTATUS wreplsrv_push_notify_wait_inform(struct wreplsrv_push_notify_state *state){	NTSTATUS status;	status =  wrepl_request_recv(state->req, state, NULL);	NT_STATUS_NOT_OK_RETURN(status);	state->stage = WREPLSRV_PUSH_NOTIFY_STAGE_DONE;	return status;}static void wreplsrv_push_notify_handler(struct wreplsrv_push_notify_state *state){	struct composite_context *c = state->c;	switch (state->stage) {	case WREPLSRV_PUSH_NOTIFY_STAGE_WAIT_CONNECT:		c->status = wreplsrv_push_notify_wait_connect(state);		break;	case WREPLSRV_PUSH_NOTIFY_STAGE_WAIT_INFORM:		c->status = wreplsrv_push_notify_wait_inform(state);		break;	case WREPLSRV_PUSH_NOTIFY_STAGE_DONE:		c->status = NT_STATUS_INTERNAL_ERROR;	}	if (state->stage == WREPLSRV_PUSH_NOTIFY_STAGE_DONE) {		c->state  = COMPOSITE_STATE_DONE;	}	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_push_notify_handler_creq(struct composite_context *creq){	struct wreplsrv_push_notify_state *state = talloc_get_type(creq->async.private_data,						   struct wreplsrv_push_notify_state);	wreplsrv_push_notify_handler(state);	return;}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);	wreplsrv_push_notify_handler(state);	return;}struct composite_context *wreplsrv_push_notify_send(TALLOC_CTX *mem_ctx, struct wreplsrv_push_notify_io *io){	struct composite_context *c = NULL;	struct wreplsrv_service *service = io->in.partner->service;	struct wreplsrv_push_notify_state *state = NULL;	enum winsrepl_partner_type partner_type;	c = talloc_zero(mem_ctx, struct composite_context);	if (!c) goto failed;	state = talloc_zero(c, struct wreplsrv_push_notify_state);	if (!state) goto failed;	state->c	= c;	state->io	= io;	if (io->in.inform) {		/* we can cache the connection in partner->push->wreplconn */		partner_type = WINSREPL_PARTNER_PUSH;		if (io->in.propagate) {			state->command	= WREPL_REPL_INFORM2;		} else {			state->command	= WREPL_REPL_INFORM;		}	} else {		/* we can NOT cache the connection */		partner_type = WINSREPL_PARTNER_NONE;		if (io->in.propagate) {			state->command	= WREPL_REPL_UPDATE2;		} else {			state->command	= WREPL_REPL_UPDATE;		}		}	c->state	= COMPOSITE_STATE_IN_PROGRESS;	c->event_ctx	= service->task->event_ctx;	c->private_data	= state;	state->stage	= WREPLSRV_PUSH_NOTIFY_STAGE_WAIT_CONNECT;	state->creq	= wreplsrv_out_connect_send(io->in.partner, partner_type, NULL);	if (!state->creq) goto failed;	state->creq->async.fn		= wreplsrv_push_notify_handler_creq;	state->creq->async.private_data	= state;	return c;failed:	talloc_free(c);	return NULL;}NTSTATUS wreplsrv_push_notify_recv(struct composite_context *c){	NTSTATUS status;	status = composite_wait(c);	talloc_free(c);	return status;}

⌨️ 快捷键说明

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