smb2_server: monitor connections with TEVENT_FD_ERROR
authorStefan Metzmacher <metze@samba.org>
Thu, 12 Jan 2023 10:35:30 +0000 (11:35 +0100)
committerRalph Boehme <slow@samba.org>
Tue, 24 Oct 2023 10:32:56 +0000 (10:32 +0000)
By asking for TEVENT_FD_ERROR we're able to fail early
when a connection to a client is broken.

In that case it does not make any sense to process
pending requests in the recv queue as it's not
possible to deliver the response to the client anyway.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Tue Oct 24 10:32:56 UTC 2023 on atb-devel-224

source3/smbd/smb2_server.c

index 67e271db0411a6b813a07027bba4768b4ec964c0..afb86abf2fc886a8d0c151406e388348444c9945 100644 (file)
@@ -314,7 +314,7 @@ static NTSTATUS smbd_initialize_smb2(struct smbXsrv_connection *xconn,
                                        xconn->client->raw_ev_ctx,
                                        xconn,
                                        xconn->transport.sock,
-                                       TEVENT_FD_READ,
+                                       TEVENT_FD_ERROR | TEVENT_FD_READ,
                                        smbd_smb2_connection_handler,
                                        xconn);
        if (xconn->transport.fde == NULL) {
@@ -5126,9 +5126,26 @@ static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
                 */
                TEVENT_FD_NOT_READABLE(xconn->transport.fde);
                TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
+               TEVENT_FD_NOT_WANTERROR(xconn->transport.fde);
                return NT_STATUS_OK;
        }
 
+       if (fde_flags & TEVENT_FD_ERROR) {
+               ret = samba_socket_poll_or_sock_error(xconn->transport.sock);
+               if (ret == -1) {
+                       err = errno;
+                       status = map_nt_error_from_unix_common(err);
+                       smbXsrv_connection_disconnect_transport(xconn,
+                                                               status);
+                       return status;
+               }
+               /* This should not happen */
+               status = NT_STATUS_REMOTE_DISCONNECT;
+               smbXsrv_connection_disconnect_transport(xconn,
+                                                       status);
+               return status;
+       }
+
        if (fde_flags & TEVENT_FD_WRITE) {
                status = smbd_smb2_flush_send_queue(xconn);
                if (!NT_STATUS_IS_OK(status)) {