summaryrefslogtreecommitdiff
path: root/source4/librpc/rpc/dcerpc.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2007-04-22 23:00:22 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:51:29 -0500
commit1912124dbfc501c5109f6ac36e125406078d408c (patch)
treea863846bd767627125f22abd26be74db66d81664 /source4/librpc/rpc/dcerpc.c
parentcc5ad07d84df94f8f2bc16fcb8015f1cf843c1e3 (diff)
downloadsamba-1912124dbfc501c5109f6ac36e125406078d408c.tar.gz
samba-1912124dbfc501c5109f6ac36e125406078d408c.tar.bz2
samba-1912124dbfc501c5109f6ac36e125406078d408c.zip
r22470: merge handling of broken connections from wins replication client code
to the rpc client code we need to always ask for read events on the socket otherwise we never get the connection error reported. shutdown the transport when a request timeout. metze (This used to be commit 3403c0cb15e08ec838b0bc834f941051fb94d124)
Diffstat (limited to 'source4/librpc/rpc/dcerpc.c')
-rw-r--r--source4/librpc/rpc/dcerpc.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
index 820516ba11..79e897313d 100644
--- a/source4/librpc/rpc/dcerpc.c
+++ b/source4/librpc/rpc/dcerpc.c
@@ -37,14 +37,17 @@ NTSTATUS dcerpc_init(void)
return NT_STATUS_OK;
}
+static void dcerpc_connection_dead(struct dcerpc_connection *conn, NTSTATUS status);
static void dcerpc_ship_next_request(struct dcerpc_connection *c);
/* destroy a dcerpc connection */
-static int dcerpc_connection_destructor(struct dcerpc_connection *c)
+static int dcerpc_connection_destructor(struct dcerpc_connection *conn)
{
- if (c->transport.shutdown_pipe) {
- c->transport.shutdown_pipe(c);
+ if (conn->dead) {
+ conn->free_skipped = True;
+ return -1;
}
+ dcerpc_connection_dead(conn, NT_STATUS_LOCAL_DISCONNECT);
return 0;
}
@@ -553,6 +556,14 @@ static int dcerpc_req_dequeue(struct rpc_request *req)
*/
static void dcerpc_connection_dead(struct dcerpc_connection *conn, NTSTATUS status)
{
+ if (conn->dead) return;
+
+ conn->dead = true;
+
+ if (conn->transport.shutdown_pipe) {
+ conn->transport.shutdown_pipe(conn, status);
+ }
+
/* all pending requests get the error */
while (conn->pending) {
struct rpc_request *req = conn->pending;
@@ -563,6 +574,11 @@ static void dcerpc_connection_dead(struct dcerpc_connection *conn, NTSTATUS stat
req->async.callback(req);
}
}
+
+ talloc_set_destructor(conn, NULL);
+ if (conn->free_skipped) {
+ talloc_free(conn);
+ }
}
/*
@@ -657,18 +673,7 @@ static void dcerpc_timeout_handler(struct event_context *ev, struct timed_event
struct timeval t, void *private)
{
struct rpc_request *req = talloc_get_type(private, struct rpc_request);
-
- if (req->state == RPC_REQUEST_DONE) {
- return;
- }
-
- dcerpc_req_dequeue(req);
-
- req->status = NT_STATUS_IO_TIMEOUT;
- req->state = RPC_REQUEST_DONE;
- if (req->async.callback) {
- req->async.callback(req);
- }
+ dcerpc_connection_dead(req->p->conn, NT_STATUS_IO_TIMEOUT);
}
/*