summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2011-11-10 09:39:23 +0100
committerVolker Lendecke <vl@samba.org>2011-11-10 17:18:53 +0100
commit5e0258fc932c280428173bb397ef5a18352e63db (patch)
tree78327a40c73e5b9b85ef96412aba862a480cb1f0 /source3/smbd
parent17f1a97a614db4ed8292544988cb6a6cf56621d8 (diff)
downloadsamba-5e0258fc932c280428173bb397ef5a18352e63db.tar.gz
samba-5e0258fc932c280428173bb397ef5a18352e63db.tar.bz2
samba-5e0258fc932c280428173bb397ef5a18352e63db.zip
s3: Avoid a race with the async echo handler
We can not read from the echo handler socket when we have the main socket locked. This leads to the echo responder to lock up sitting in the fcntl lock while the parent wants to read the remainder of a large packet.
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/process.c61
1 files changed, 28 insertions, 33 deletions
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 0ad554228b..82dd51048e 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -2217,46 +2217,41 @@ static void smbd_server_connection_read_handler(
NTSTATUS status;
uint32_t seqnum;
- bool from_client = (sconn->sock == fd);
+ bool from_client;
+
+ if (lp_async_smb_echo_handler()
+ && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
+ /*
+ * This is the super-ugly hack to prefer the packets
+ * forwarded by the echo handler over the ones by the
+ * client directly
+ */
+ fd = sconn->smb1.echo_handler.trusted_fd;
+ }
+
+ from_client = (sconn->sock == fd);
if (from_client) {
smbd_lock_socket(sconn);
- if (lp_async_smb_echo_handler()) {
-
- if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
- /*
- * This is the super-ugly hack to
- * prefer the packets forwarded by the
- * echo handler over the ones by the
- * client directly
- */
- fd = sconn->smb1.echo_handler.trusted_fd;
- } else if (!fd_is_readable(fd)) {
- DEBUG(10,("the echo listener was faster\n"));
- smbd_unlock_socket(sconn);
- return;
- }
+ if (!fd_is_readable(fd)) {
+ DEBUG(10,("the echo listener was faster\n"));
+ smbd_unlock_socket(sconn);
+ return;
}
+ }
+
+ /* TODO: make this completely nonblocking */
+ status = receive_smb_talloc(mem_ctx, sconn, fd,
+ (char **)(void *)&inbuf,
+ 0, /* timeout */
+ &unread_bytes,
+ &encrypted,
+ &inbuf_len, &seqnum,
+ false /* trusted channel */);
- /* TODO: make this completely nonblocking */
- status = receive_smb_talloc(mem_ctx, sconn, fd,
- (char **)(void *)&inbuf,
- 0, /* timeout */
- &unread_bytes,
- &encrypted,
- &inbuf_len, &seqnum,
- false /* trusted channel */);
+ if (from_client) {
smbd_unlock_socket(sconn);
- } else {
- /* TODO: make this completely nonblocking */
- status = receive_smb_talloc(mem_ctx, sconn, fd,
- (char **)(void *)&inbuf,
- 0, /* timeout */
- &unread_bytes,
- &encrypted,
- &inbuf_len, &seqnum,
- true /* trusted channel */);
}
if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {