diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-06-16 23:19:03 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:18:17 -0500 |
commit | d13e788f20743989ff0d76b13262793027dc66bd (patch) | |
tree | 752770e7ff922e5e0b210cda2a4f9574ce44985b /source4/libcli/raw/clitransport.c | |
parent | be8139c1e75cf19f4590e64c979bf8b2199b7c89 (diff) | |
download | samba-d13e788f20743989ff0d76b13262793027dc66bd.tar.gz samba-d13e788f20743989ff0d76b13262793027dc66bd.tar.bz2 samba-d13e788f20743989ff0d76b13262793027dc66bd.zip |
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)
Diffstat (limited to 'source4/libcli/raw/clitransport.c')
-rw-r--r-- | source4/libcli/raw/clitransport.c | 46 |
1 files changed, 46 insertions, 0 deletions
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); } |