svn commit: samba r10530 - in branches/SAMBA_4_0/source/libcli/wrepl: .

metze at samba.org metze at samba.org
Tue Sep 27 10:31:58 GMT 2005


Author: metze
Date: 2005-09-27 10:31:57 +0000 (Tue, 27 Sep 2005)
New Revision: 10530

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=10530

Log:
- fix some crash bugs when we lost the connection...

metze
Modified:
   branches/SAMBA_4_0/source/libcli/wrepl/winsrepl.c
   branches/SAMBA_4_0/source/libcli/wrepl/winsrepl.h


Changeset:
Modified: branches/SAMBA_4_0/source/libcli/wrepl/winsrepl.c
===================================================================
--- branches/SAMBA_4_0/source/libcli/wrepl/winsrepl.c	2005-09-27 10:29:13 UTC (rev 10529)
+++ branches/SAMBA_4_0/source/libcli/wrepl/winsrepl.c	2005-09-27 10:31:57 UTC (rev 10530)
@@ -31,6 +31,8 @@
 */
 static void wrepl_socket_dead(struct wrepl_socket *wrepl_socket)
 {
+	wrepl_socket->dead = True;
+
 	event_set_fd_flags(wrepl_socket->fde, 0);
 
 	while (wrepl_socket->send_queue) {
@@ -118,7 +120,10 @@
 					  req->buffer.data + req->num_read,
 					  4 - req->num_read,
 					  &nread, 0);
-		if (NT_STATUS_IS_ERR(req->status)) goto failed;
+		if (NT_STATUS_IS_ERR(req->status)) {
+			wrepl_socket_dead(wrepl_socket);
+			return;
+		}
 		if (!NT_STATUS_IS_OK(req->status)) return;
 
 		req->num_read += nread;
@@ -140,7 +145,10 @@
 				  req->buffer.data + req->num_read,
 				  req->buffer.length - req->num_read,
 				  &nread, 0);
-	if (NT_STATUS_IS_ERR(req->status)) goto failed;
+	if (NT_STATUS_IS_ERR(req->status)) {
+		wrepl_socket_dead(wrepl_socket);
+		return;
+	}
 	if (!NT_STATUS_IS_OK(req->status)) return;
 
 	req->num_read += nread;
@@ -275,6 +283,7 @@
 
 	wrepl_socket->send_queue = NULL;
 	wrepl_socket->recv_queue = NULL;
+	wrepl_socket->dead       = False;
 
 	wrepl_socket->fde = event_add_fd(wrepl_socket->event_ctx, wrepl_socket, 
 					 socket_get_fd(wrepl_socket->sock), 
@@ -368,8 +377,37 @@
 	return wrepl_connect_recv(req);
 }
 
+/* 
+   callback from wrepl_request_trigger() 
+*/
+static void wrepl_request_trigger_handler(struct event_context *ev, struct timed_event *te,
+					  struct timeval t, void *ptr)
+{
+	struct wrepl_request *req = talloc_get_type(ptr, struct wrepl_request);
+	if (req->async.fn) {
+		/*
+		 * the event is a child of req,
+		 * and req will be free'ed by the callback fn
+		 * but the events code wants to free the event itself
+		 */
+		talloc_steal(ev, te);
+		req->async.fn(req);
+	}
+}
 
 /*
+  trigger an immediate event on a wrepl_request
+*/
+static void wrepl_request_trigger(struct wrepl_request *req)
+{
+	/* a zero timeout means immediate */
+	event_add_timed(req->wrepl_socket->event_ctx,
+			req, timeval_zero(),
+			wrepl_request_trigger_handler, req);
+}
+
+
+/*
   send a generic wins replication request
 */
 struct wrepl_request *wrepl_request_send(struct wrepl_socket *wrepl_socket,
@@ -381,12 +419,20 @@
 	req = talloc_zero(wrepl_socket, struct wrepl_request);
 	if (req == NULL) goto failed;
 
+	if (wrepl_socket->dead) {
+		req->wrepl_socket = wrepl_socket;
+		req->state        = WREPL_REQUEST_ERROR;
+		req->status       = NT_STATUS_INVALID_CONNECTION;
+		wrepl_request_trigger(req);
+		return req;
+	}
+
 	req->wrepl_socket = wrepl_socket;
 	req->state        = WREPL_REQUEST_SEND;
 
 	wrap.packet = *packet;
 	req->status = ndr_push_struct_blob(&req->buffer, req, &wrap,
-					   (ndr_push_flags_fn_t)ndr_push_wrepl_wrap);	
+					   (ndr_push_flags_fn_t)ndr_push_wrepl_wrap);
 	if (!NT_STATUS_IS_OK(req->status)) goto failed;
 
 	if (DEBUGLVL(10)) {
@@ -468,6 +514,7 @@
 	struct wrepl_packet *packet=NULL;
 	NTSTATUS status;
 	status = wrepl_request_recv(req, req->wrepl_socket, &packet);
+	NT_STATUS_NOT_OK_RETURN(status);
 	if (packet->mess_type != WREPL_START_ASSOCIATION_REPLY) {
 		status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
 	}
@@ -527,6 +574,7 @@
 	int i;
 
 	status = wrepl_request_recv(req, req->wrepl_socket, &packet);
+	NT_STATUS_NOT_OK_RETURN(status);
 	if (packet->mess_type != WREPL_REPLICATION) {
 		status = NT_STATUS_NETWORK_ACCESS_DENIED;
 	} else if (packet->message.replication.command != WREPL_REPL_TABLE_REPLY) {
@@ -630,6 +678,7 @@
 	int i;
 
 	status = wrepl_request_recv(req, req->wrepl_socket, &packet);
+	NT_STATUS_NOT_OK_RETURN(status);
 	if (packet->mess_type != WREPL_REPLICATION ||
 	    packet->message.replication.command != WREPL_REPL_SEND_REPLY) {
 		status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;

Modified: branches/SAMBA_4_0/source/libcli/wrepl/winsrepl.h
===================================================================
--- branches/SAMBA_4_0/source/libcli/wrepl/winsrepl.h	2005-09-27 10:29:13 UTC (rev 10529)
+++ branches/SAMBA_4_0/source/libcli/wrepl/winsrepl.h	2005-09-27 10:31:57 UTC (rev 10530)
@@ -38,6 +38,9 @@
 
 	/* the fd event */
 	struct fd_event *fde;
+
+	/* remember is the socket is dead */
+	BOOL dead;
 };
 
 enum wrepl_request_state {



More information about the samba-cvs mailing list