From 493a37ba663686b7bee3f7093d6650a24250f101 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 23 Apr 2004 04:21:22 +0000 Subject: r335: added much better handling of servers that die unexpectedly during a request (a dead socket). I discovered this when testing against Sun's PC-NetLink. cleaned up the naming of some of the samr requests add IDL and test code for samr_QueryGroupMember(), samr_SetMemberAttributesOfGroup() and samr_Shutdown(). (actually, I didn't leave the samr_Shutdown() test in, as its fatal to windows servers due to doing exactly what it says it does). (This used to be commit 925bc2622c105dee4ffff809c6c35cd209a839f8) --- source4/libcli/raw/clisocket.c | 26 +++++++++++++++++++++++--- source4/libcli/raw/clitransport.c | 8 ++++++++ source4/libcli/raw/rawrequest.c | 11 +++++++---- source4/libcli/raw/rawtrans.c | 1 - 4 files changed, 38 insertions(+), 8 deletions(-) (limited to 'source4/libcli/raw') diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index f596cba854..4dae7d517d 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -74,15 +74,25 @@ BOOL cli_sock_connect(struct cli_socket *sock, struct in_addr *ip, int port) } +/**************************************************************************** + mark the socket as dead +****************************************************************************/ +void cli_sock_dead(struct cli_socket *sock) +{ + if (sock->fd != -1) { + close(sock->fd); + sock->fd = -1; + } +} + /**************************************************************************** reduce socket reference count - if it becomes zero then close ****************************************************************************/ void cli_sock_close(struct cli_socket *sock) { sock->reference_count--; - if (sock->reference_count <= 0 && sock->fd != -1) { - close(sock->fd); - sock->fd = -1; + if (sock->reference_count <= 0) { + cli_sock_dead(sock); } } @@ -99,6 +109,11 @@ void cli_sock_set_options(struct cli_socket *sock, const char *options) ****************************************************************************/ ssize_t cli_sock_write(struct cli_socket *sock, const char *data, size_t len) { + if (sock->fd == -1) { + errno = EIO; + return -1; + } + return write_data(sock->fd, data, len); } @@ -108,6 +123,11 @@ ssize_t cli_sock_write(struct cli_socket *sock, const char *data, size_t len) ****************************************************************************/ ssize_t cli_sock_read(struct cli_socket *sock, char *data, size_t len) { + if (sock->fd == -1) { + errno = EIO; + return -1; + } + return read_data(sock->fd, data, len); } diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index 62152bbe4d..b8eef65c7f 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -60,6 +60,14 @@ void cli_transport_close(struct cli_transport *transport) } } +/* + mark the transport as dead +*/ +void cli_transport_dead(struct cli_transport *transport) +{ + cli_sock_dead(transport->socket); +} + /**************************************************************************** diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index 321d43f220..35a2d363df 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -40,9 +40,11 @@ NTSTATUS cli_request_destroy(struct cli_request *req) _send() call fails completely */ if (!req) return NT_STATUS_UNSUCCESSFUL; - /* remove it from the list of pending requests (a null op if - its not in the list) */ - DLIST_REMOVE(req->transport->pending_requests, req); + if (req->transport) { + /* remove it from the list of pending requests (a null op if + its not in the list) */ + DLIST_REMOVE(req->transport->pending_requests, req); + } /* ahh, its so nice to destroy a complex structure in such a simple way! */ @@ -306,11 +308,12 @@ BOOL cli_request_receive(struct cli_request *req) /* keep receiving packets until this one is replied to */ while (!req->in.buffer) { if (!cli_transport_select(req->transport)) { + req->status = NT_STATUS_UNSUCCESSFUL; return False; } if (!cli_request_receive_next(req->transport)) { - cli_transport_close(req->transport); + cli_transport_dead(req->transport); req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; return False; } diff --git a/source4/libcli/raw/rawtrans.c b/source4/libcli/raw/rawtrans.c index f7a3b4aa43..1fd91b29d7 100644 --- a/source4/libcli/raw/rawtrans.c +++ b/source4/libcli/raw/rawtrans.c @@ -64,7 +64,6 @@ NTSTATUS smb_raw_trans2_recv(struct cli_request *req, parms->out.params.data = NULL; if (!cli_request_receive(req)) { - req->status = NT_STATUS_UNSUCCESSFUL; return cli_request_destroy(req); } -- cgit