5f8e325d63f97a2672410d6ddc76e7011e6cad43
[kai/samba-autobuild/.git] / source4 / torture / smb2 / lease_break_handler.c
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 void torture_lease_break_callback(struct smb2_request *req)
35 {
36         NTSTATUS status;
37
38         status = smb2_lease_break_ack_recv(req, &lease_break_info.lease_break_ack);
39         if (!NT_STATUS_IS_OK(status))
40                 lease_break_info.failures++;
41
42         return;
43 }
44
45 /* a lease break request handler */
46 bool torture_lease_handler(struct smb2_transport *transport,
47                            const struct smb2_lease_break *lb,
48                            void *private_data)
49 {
50         struct smb2_tree *tree = private_data;
51         struct smb2_lease_break_ack io;
52         struct smb2_request *req;
53
54         lease_break_info.lease_transport = transport;
55         lease_break_info.lease_break = *lb;
56         lease_break_info.count++;
57
58         if (lease_break_info.lease_skip_ack) {
59                 return true;
60         }
61
62         if (lb->break_flags & SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED) {
63                 ZERO_STRUCT(io);
64                 io.in.lease.lease_key = lb->current_lease.lease_key;
65                 io.in.lease.lease_state = lb->new_lease_state;
66
67                 req = smb2_lease_break_ack_send(tree, &io);
68                 req->async.fn = torture_lease_break_callback;
69                 req->async.private_data = NULL;
70         }
71
72         return true;
73 }
74
75 /*
76    Timer handler function notifies the registering function that time is up
77 */
78 static void timeout_cb(struct tevent_context *ev,
79                        struct tevent_timer *te,
80                        struct timeval current_time,
81                        void *private_data)
82 {
83         bool *timesup = (bool *)private_data;
84         *timesup = true;
85         return;
86 }
87
88 /*
89    Wait a short period of time to receive a single oplock break request
90 */
91 void torture_wait_for_lease_break(struct torture_context *tctx)
92 {
93         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
94         struct tevent_timer *te = NULL;
95         struct timeval ne;
96         bool timesup = false;
97         int old_count = lease_break_info.count;
98
99         /* Wait .1 seconds for an lease break */
100         ne = tevent_timeval_current_ofs(0, 100000);
101
102         te = tevent_add_timer(tctx->ev, tmp_ctx, ne, timeout_cb, &timesup);
103         if (te == NULL) {
104                 torture_comment(tctx, "Failed to wait for an oplock break. "
105                                       "test results may not be accurate.");
106                 goto done;
107         }
108
109         while (!timesup && lease_break_info.count < old_count + 1) {
110                 if (tevent_loop_once(tctx->ev) != 0) {
111                         torture_comment(tctx, "Failed to wait for an oplock "
112                                               "break. test results may not be "
113                                               "accurate.");
114                         goto done;
115                 }
116         }
117
118 done:
119         /* We don't know if the timed event fired and was freed, we received
120          * our oplock break, or some other event triggered the loop.  Thus,
121          * we create a tmp_ctx to be able to safely free/remove the timed
122          * event in all 3 cases. */
123         talloc_free(tmp_ctx);
124
125         return;
126 }