diff options
author | Stefan Metzmacher <metze@samba.org> | 2012-03-07 16:54:18 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2012-03-07 18:44:24 +0100 |
commit | 7b1fb088421565f1752acde02377237e4ca19248 (patch) | |
tree | cbba0899de6e78c4df31be7196fb78f4353b7058 /source4 | |
parent | 01c404a67c3321c8959b47841db5c1900b4ebac4 (diff) | |
download | samba-7b1fb088421565f1752acde02377237e4ca19248.tar.gz samba-7b1fb088421565f1752acde02377237e4ca19248.tar.bz2 samba-7b1fb088421565f1752acde02377237e4ca19248.zip |
s4:librpc/rpc: make dcerpc_bh_raw_call_* more robust against disconnects and timeouts
Using tevent_req_defer_callback() should make the situation a bit better,
until we have a common robust low level dcerpc library.
metze
Autobuild-User: Stefan Metzmacher <metze@samba.org>
Autobuild-Date: Wed Mar 7 18:44:24 CET 2012 on sn-devel-104
Diffstat (limited to 'source4')
-rw-r--r-- | source4/librpc/rpc/dcerpc.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 8317778bc8..599ad786c6 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -194,6 +194,7 @@ static uint32_t dcerpc_bh_set_timeout(struct dcerpc_binding_handle *h, } struct dcerpc_bh_raw_call_state { + struct tevent_context *ev; struct dcerpc_binding_handle *h; DATA_BLOB in_data; DATA_BLOB out_data; @@ -223,6 +224,7 @@ static struct tevent_req *dcerpc_bh_raw_call_send(TALLOC_CTX *mem_ctx, if (req == NULL) { return NULL; } + state->ev = ev; state->h = h; state->in_data.data = discard_const_p(uint8_t, in_data); state->in_data.length = in_length; @@ -268,6 +270,19 @@ static void dcerpc_bh_raw_call_done(struct rpc_request *subreq) if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) { status = dcerpc_fault_to_nt_status(fault_code); } + + /* + * We trigger the callback in the next event run + * because the code in this file might trigger + * multiple request callbacks from within a single + * while loop. + * + * In order to avoid segfaults from within + * dcerpc_connection_dead() we call + * tevent_req_defer_callback(). + */ + tevent_req_defer_callback(req, state->ev); + if (!NT_STATUS_IS_OK(status)) { tevent_req_nterror(req, status); return; |