mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
smbXcli: add support for tevent_req_cancel() on smbXcli_req
metze
This commit is contained in:
parent
91ffe696aa
commit
0995d68d59
@ -618,6 +618,30 @@ static int smbXcli_req_destructor(struct tevent_req *req)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool smb1cli_req_cancel(struct tevent_req *req);
|
||||||
|
static bool smb2cli_req_cancel(struct tevent_req *req);
|
||||||
|
|
||||||
|
static bool smbXcli_req_cancel(struct tevent_req *req)
|
||||||
|
{
|
||||||
|
struct smbXcli_req_state *state =
|
||||||
|
tevent_req_data(req,
|
||||||
|
struct smbXcli_req_state);
|
||||||
|
|
||||||
|
if (!smbXcli_conn_is_connected(state->conn)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->conn->protocol == PROTOCOL_NONE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->conn->protocol >= PROTOCOL_SMB2_02) {
|
||||||
|
return smb2cli_req_cancel(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
return smb1cli_req_cancel(req);
|
||||||
|
}
|
||||||
|
|
||||||
static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn);
|
static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn);
|
||||||
|
|
||||||
bool smbXcli_req_set_pending(struct tevent_req *req)
|
bool smbXcli_req_set_pending(struct tevent_req *req)
|
||||||
@ -645,6 +669,7 @@ bool smbXcli_req_set_pending(struct tevent_req *req)
|
|||||||
pending[num_pending] = req;
|
pending[num_pending] = req;
|
||||||
conn->pending = pending;
|
conn->pending = pending;
|
||||||
talloc_set_destructor(req, smbXcli_req_destructor);
|
talloc_set_destructor(req, smbXcli_req_destructor);
|
||||||
|
tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
|
||||||
|
|
||||||
if (!smbXcli_conn_receive_next(conn)) {
|
if (!smbXcli_conn_receive_next(conn)) {
|
||||||
/*
|
/*
|
||||||
@ -900,6 +925,62 @@ static void smb1cli_req_flags(enum protocol_types protocol,
|
|||||||
*_flags2 = flags2;
|
*_flags2 = flags2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void smb1cli_req_cancel_done(struct tevent_req *subreq);
|
||||||
|
|
||||||
|
static bool smb1cli_req_cancel(struct tevent_req *req)
|
||||||
|
{
|
||||||
|
struct smbXcli_req_state *state =
|
||||||
|
tevent_req_data(req,
|
||||||
|
struct smbXcli_req_state);
|
||||||
|
uint8_t flags;
|
||||||
|
uint16_t flags2;
|
||||||
|
uint32_t pid;
|
||||||
|
uint16_t tid;
|
||||||
|
uint16_t uid;
|
||||||
|
uint16_t mid;
|
||||||
|
struct tevent_req *subreq;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
flags = CVAL(state->smb1.hdr, HDR_FLG);
|
||||||
|
flags2 = SVAL(state->smb1.hdr, HDR_FLG2);
|
||||||
|
pid = SVAL(state->smb1.hdr, HDR_PID);
|
||||||
|
pid |= SVAL(state->smb1.hdr, HDR_PIDHIGH)<<16;
|
||||||
|
tid = SVAL(state->smb1.hdr, HDR_TID);
|
||||||
|
uid = SVAL(state->smb1.hdr, HDR_UID);
|
||||||
|
mid = SVAL(state->smb1.hdr, HDR_MID);
|
||||||
|
|
||||||
|
subreq = smb1cli_req_create(state, state->ev,
|
||||||
|
state->conn,
|
||||||
|
SMBntcancel,
|
||||||
|
flags, 0,
|
||||||
|
flags2, 0,
|
||||||
|
0, /* timeout */
|
||||||
|
pid, tid, uid,
|
||||||
|
0, NULL, /* vwv */
|
||||||
|
0, NULL); /* bytes */
|
||||||
|
if (subreq == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
smb1cli_req_set_mid(subreq, mid);
|
||||||
|
|
||||||
|
status = smb1cli_req_chain_submit(&subreq, 1);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
TALLOC_FREE(subreq);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
smb1cli_req_set_mid(subreq, 0);
|
||||||
|
|
||||||
|
tevent_req_set_callback(subreq, smb1cli_req_cancel_done, NULL);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void smb1cli_req_cancel_done(struct tevent_req *subreq)
|
||||||
|
{
|
||||||
|
/* we do not care about the result */
|
||||||
|
TALLOC_FREE(subreq);
|
||||||
|
}
|
||||||
|
|
||||||
struct tevent_req *smb1cli_req_create(TALLOC_CTX *mem_ctx,
|
struct tevent_req *smb1cli_req_create(TALLOC_CTX *mem_ctx,
|
||||||
struct tevent_context *ev,
|
struct tevent_context *ev,
|
||||||
struct smbXcli_conn *conn,
|
struct smbXcli_conn *conn,
|
||||||
@ -1145,6 +1226,8 @@ static NTSTATUS smb1cli_req_writev_submit(struct tevent_req *req,
|
|||||||
state->conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
|
state->conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
|
||||||
|
|
||||||
subreq = writev_send(state, state->ev, state->conn->outgoing,
|
subreq = writev_send(state, state->ev, state->conn->outgoing,
|
||||||
state->conn->fd, false, iov, iov_count);
|
state->conn->fd, false, iov, iov_count);
|
||||||
if (subreq == NULL) {
|
if (subreq == NULL) {
|
||||||
@ -2007,6 +2090,68 @@ void smb2cli_conn_set_max_credits(struct smbXcli_conn *conn,
|
|||||||
conn->smb2.max_credits = max_credits;
|
conn->smb2.max_credits = max_credits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void smb2cli_req_cancel_done(struct tevent_req *subreq);
|
||||||
|
|
||||||
|
static bool smb2cli_req_cancel(struct tevent_req *req)
|
||||||
|
{
|
||||||
|
struct smbXcli_req_state *state =
|
||||||
|
tevent_req_data(req,
|
||||||
|
struct smbXcli_req_state);
|
||||||
|
uint32_t flags = IVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
|
||||||
|
uint32_t pid = IVAL(state->smb2.hdr, SMB2_HDR_PID);
|
||||||
|
uint32_t tid = IVAL(state->smb2.hdr, SMB2_HDR_TID);
|
||||||
|
uint64_t mid = BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID);
|
||||||
|
uint64_t aid = BVAL(state->smb2.hdr, SMB2_HDR_ASYNC_ID);
|
||||||
|
struct smbXcli_session *session = state->session;
|
||||||
|
uint8_t *fixed = state->smb2.pad;
|
||||||
|
uint16_t fixed_len = 4;
|
||||||
|
struct tevent_req *subreq;
|
||||||
|
struct smbXcli_req_state *substate;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
SSVAL(fixed, 0, 0x04);
|
||||||
|
SSVAL(fixed, 2, 0);
|
||||||
|
|
||||||
|
subreq = smb2cli_req_create(state, state->ev,
|
||||||
|
state->conn,
|
||||||
|
SMB2_OP_CANCEL,
|
||||||
|
flags, 0,
|
||||||
|
0, /* timeout */
|
||||||
|
pid, tid, session,
|
||||||
|
fixed, fixed_len,
|
||||||
|
NULL, 0);
|
||||||
|
if (subreq == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
substate = tevent_req_data(subreq, struct smbXcli_req_state);
|
||||||
|
|
||||||
|
if (flags & SMB2_HDR_FLAG_ASYNC) {
|
||||||
|
mid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SIVAL(substate->smb2.hdr, SMB2_HDR_FLAGS, flags);
|
||||||
|
SIVAL(substate->smb2.hdr, SMB2_HDR_PID, pid);
|
||||||
|
SIVAL(substate->smb2.hdr, SMB2_HDR_TID, tid);
|
||||||
|
SBVAL(substate->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
|
||||||
|
SBVAL(substate->smb2.hdr, SMB2_HDR_ASYNC_ID, aid);
|
||||||
|
|
||||||
|
status = smb2cli_req_compound_submit(&subreq, 1);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
TALLOC_FREE(subreq);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
tevent_req_set_callback(subreq, smb2cli_req_cancel_done, NULL);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void smb2cli_req_cancel_done(struct tevent_req *subreq)
|
||||||
|
{
|
||||||
|
/* we do not care about the result */
|
||||||
|
TALLOC_FREE(subreq);
|
||||||
|
}
|
||||||
|
|
||||||
struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
|
struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
|
||||||
struct tevent_context *ev,
|
struct tevent_context *ev,
|
||||||
struct smbXcli_conn *conn,
|
struct smbXcli_conn *conn,
|
||||||
@ -2121,6 +2266,7 @@ NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
|
|||||||
int hdr_iov;
|
int hdr_iov;
|
||||||
size_t reqlen;
|
size_t reqlen;
|
||||||
bool ret;
|
bool ret;
|
||||||
|
uint16_t opcode;
|
||||||
uint64_t avail;
|
uint64_t avail;
|
||||||
uint16_t charge;
|
uint16_t charge;
|
||||||
uint16_t credits;
|
uint16_t credits;
|
||||||
@ -2142,6 +2288,11 @@ NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
|
|||||||
return NT_STATUS_REVISION_MISMATCH;
|
return NT_STATUS_REVISION_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
|
||||||
|
if (opcode == SMB2_OP_CANCEL) {
|
||||||
|
goto skip_credits;
|
||||||
|
}
|
||||||
|
|
||||||
avail = UINT64_MAX - state->conn->smb2.mid;
|
avail = UINT64_MAX - state->conn->smb2.mid;
|
||||||
if (avail < 1) {
|
if (avail < 1) {
|
||||||
return NT_STATUS_CONNECTION_ABORTED;
|
return NT_STATUS_CONNECTION_ABORTED;
|
||||||
@ -2179,6 +2330,7 @@ NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
|
|||||||
SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT, credits);
|
SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT, credits);
|
||||||
SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
|
SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
|
||||||
|
|
||||||
|
skip_credits:
|
||||||
hdr_iov = num_iov;
|
hdr_iov = num_iov;
|
||||||
iov[num_iov].iov_base = state->smb2.hdr;
|
iov[num_iov].iov_base = state->smb2.hdr;
|
||||||
iov[num_iov].iov_len = sizeof(state->smb2.hdr);
|
iov[num_iov].iov_len = sizeof(state->smb2.hdr);
|
||||||
|
Loading…
Reference in New Issue
Block a user