From d13e788f20743989ff0d76b13262793027dc66bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 16 Jun 2005 23:19:03 +0000 Subject: r7654: - add a timeout to all smb requests (default 60 seconds) - add a request destructor, to make it safe to destroy a pending request with talloc_free() (This used to be commit 72c6988767249caa585f37fec4c0afbf41557ec2) --- source4/libcli/raw/clitransport.c | 46 +++++++++++++++++++++++++++++++++++++++ source4/libcli/raw/libcliraw.h | 4 ++++ 2 files changed, 50 insertions(+) (limited to 'source4/libcli') diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 05833b2f9a..999795b81e 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -79,6 +79,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock, transport->options.use_spnego = lp_use_spnego(); transport->options.max_xmit = lp_max_xmit(); transport->options.max_mux = lp_maxmux(); + transport->options.request_timeout = SMB_REQUEST_TIMEOUT; transport->negotiate.max_xmit = transport->options.max_xmit; @@ -580,6 +581,42 @@ BOOL smbcli_transport_process(struct smbcli_transport *transport) return True; } +/* + handle timeouts of individual smb requests +*/ +static void smbcli_timeout_handler(struct event_context *ev, struct timed_event *te, + struct timeval t, void *private) +{ + struct smbcli_request *req = talloc_get_type(private, struct smbcli_request); + + if (req->state == SMBCLI_REQUEST_SEND) { + DLIST_REMOVE(req->transport->pending_send, req); + } + if (req->state == SMBCLI_REQUEST_RECV) { + DLIST_REMOVE(req->transport->pending_recv, req); + } + req->status = NT_STATUS_IO_TIMEOUT; + req->state = SMBCLI_REQUEST_ERROR; + if (req->async.fn) { + req->async.fn(req); + } +} + + +/* + destroy a request +*/ +static int smbcli_request_destructor(void *ptr) +{ + struct smbcli_request *req = talloc_get_type(ptr, struct smbcli_request); + if (req->state == SMBCLI_REQUEST_SEND) { + DLIST_REMOVE(req->transport->pending_send, req); + } + if (req->state == SMBCLI_REQUEST_RECV) { + DLIST_REMOVE(req->transport->pending_recv, req); + } + return 0; +} /* @@ -600,4 +637,13 @@ void smbcli_transport_send(struct smbcli_request *req) /* make sure we look for write events */ smbcli_transport_write_enable(req->transport); + + /* add a timeout */ + if (req->transport->options.request_timeout) { + event_add_timed(req->transport->socket->event.ctx, req, + timeval_current_ofs(req->transport->options.request_timeout, 0), + smbcli_timeout_handler, req); + } + + talloc_set_destructor(req, smbcli_request_destructor); } diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index d7414a237e..2794a22da2 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -28,6 +28,9 @@ struct smbcli_request; /* forward declare */ struct smbcli_session; /* forward declare */ struct smbcli_transport; /* forward declare */ +/* default timeout for all smb requests */ +#define SMB_REQUEST_TIMEOUT 60 + /* context that will be and has been negotiated between the client and server */ struct smbcli_negotiate { /* @@ -88,6 +91,7 @@ struct smbcli_options { uint_t use_spnego:1; uint32_t max_xmit; uint16_t max_mux; + int request_timeout; }; /* this is the context for the client transport layer */ -- cgit