LCOV - code coverage report
Current view: top level - source4/torture/smb2 - lease_break_handler.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 49 55 89.1 %
Date: 2021-08-25 13:27:56 Functions: 4 5 80.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    test suite for SMB2 leases
       5             : 
       6             :    Copyright (C) Zachary Loafman 2009
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include <tevent.h>
      24             : #include "libcli/smb2/smb2.h"
      25             : #include "libcli/smb2/smb2_calls.h"
      26             : #include "torture/torture.h"
      27             : #include "torture/smb2/proto.h"
      28             : #include "torture/util.h"
      29             : #include "libcli/smb/smbXcli_base.h"
      30             : #include "lease_break_handler.h"
      31             : 
      32             : struct lease_break_info lease_break_info;
      33             : 
      34          98 : void torture_lease_break_callback(struct smb2_request *req)
      35             : {
      36             :         NTSTATUS status;
      37             : 
      38          98 :         status = smb2_lease_break_ack_recv(req, &lease_break_info.lease_break_ack);
      39          98 :         if (!NT_STATUS_IS_OK(status))
      40           2 :                 lease_break_info.failures++;
      41             : 
      42          98 :         return;
      43             : }
      44             : 
      45             : /* a lease break request handler */
      46         250 : bool torture_lease_handler(struct smb2_transport *transport,
      47             :                            const struct smb2_lease_break *lb,
      48             :                            void *private_data)
      49             : {
      50         250 :         struct smb2_tree *tree = private_data;
      51             :         struct smb2_lease_break_ack io;
      52             :         struct smb2_request *req;
      53         250 :         const char *action = NULL;
      54         250 :         char *ls = smb2_util_lease_state_string(lease_break_info.tctx,
      55             :                                                 lb->new_lease_state);
      56             : 
      57         250 :         if (lb->break_flags & SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED) {
      58         232 :                 action = "acking";
      59             :         } else {
      60          18 :                 action = "received";
      61             :         }
      62             : 
      63         250 :         lease_break_info.lease_transport = transport;
      64         250 :         lease_break_info.lease_break = *lb;
      65         250 :         lease_break_info.count++;
      66             : 
      67         250 :         if (lease_break_info.lease_skip_ack) {
      68         136 :                 torture_comment(lease_break_info.tctx,
      69             :                         "transport[%p] Skip %s to %s in lease handler\n",
      70             :                         transport, action, ls);
      71         136 :                 return true;
      72             :         }
      73             : 
      74         114 :         torture_comment(lease_break_info.tctx,
      75             :                 "transport[%p] %s to %s in lease handler\n",
      76             :                 transport, action, ls);
      77             : 
      78         114 :         if (lb->break_flags & SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED) {
      79          98 :                 ZERO_STRUCT(io);
      80          98 :                 io.in.lease.lease_key = lb->current_lease.lease_key;
      81          98 :                 io.in.lease.lease_state = lb->new_lease_state;
      82             : 
      83          98 :                 req = smb2_lease_break_ack_send(tree, &io);
      84          98 :                 req->async.fn = torture_lease_break_callback;
      85          98 :                 req->async.private_data = NULL;
      86             :         }
      87             : 
      88         114 :         return true;
      89             : }
      90             : 
      91             : /*
      92             :  * A lease break handler which ignores incoming lease break requests
      93             :  * To be used in cases where the client is expected to ignore incoming
      94             :  * lease break requests
      95             :  */
      96           0 : bool torture_lease_ignore_handler(struct smb2_transport *transport,
      97             :                            const struct smb2_lease_break *lb,
      98             :                            void *private_data)
      99             : {
     100           0 :         return true;
     101             : }
     102             : 
     103             : /*
     104             :    Timer handler function notifies the registering function that time is up
     105             : */
     106         492 : static void timeout_cb(struct tevent_context *ev,
     107             :                        struct tevent_timer *te,
     108             :                        struct timeval current_time,
     109             :                        void *private_data)
     110             : {
     111         492 :         bool *timesup = (bool *)private_data;
     112         492 :         *timesup = true;
     113         492 :         return;
     114             : }
     115             : 
     116             : /*
     117             :    Wait a short period of time to receive a single oplock break request
     118             : */
     119         576 : void torture_wait_for_lease_break(struct torture_context *tctx)
     120             : {
     121         576 :         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
     122         576 :         struct tevent_timer *te = NULL;
     123             :         struct timeval ne;
     124         576 :         bool timesup = false;
     125         576 :         int old_count = lease_break_info.count;
     126             : 
     127             :         /* Wait 1 second for an lease break */
     128         576 :         ne = tevent_timeval_current_ofs(0, 1000000);
     129             : 
     130         576 :         te = tevent_add_timer(tctx->ev, tmp_ctx, ne, timeout_cb, &timesup);
     131         576 :         if (te == NULL) {
     132           0 :                 torture_comment(tctx, "Failed to wait for an lease break. "
     133             :                                       "test results may not be accurate.\n");
     134           0 :                 goto done;
     135             :         }
     136             : 
     137         576 :         torture_comment(tctx, "Waiting for a potential lease break...\n");
     138         576 :         while (!timesup && lease_break_info.count < old_count + 1) {
     139         909 :                 if (tevent_loop_once(tctx->ev) != 0) {
     140           0 :                         torture_comment(tctx, "Failed to wait for a lease "
     141             :                                               "break. test results may not be "
     142             :                                               "accurate.\n");
     143           0 :                         goto done;
     144             :                 }
     145             :         }
     146         576 :         if (timesup) {
     147         492 :                 torture_comment(tctx, "... waiting for a lease break timed out\n");
     148             :         } else {
     149          84 :                 torture_comment(tctx, "Got %u lease breaks\n",
     150          84 :                                 lease_break_info.count - old_count);
     151             :         }
     152             : 
     153         576 : done:
     154             :         /* We don't know if the timed event fired and was freed, we received
     155             :          * our oplock break, or some other event triggered the loop.  Thus,
     156             :          * we create a tmp_ctx to be able to safely free/remove the timed
     157             :          * event in all 3 cases. */
     158         576 :         talloc_free(tmp_ctx);
     159             : 
     160         576 :         return;
     161             : }

Generated by: LCOV version 1.13