summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/aio.c8
-rw-r--r--source3/smbd/blocking.c6
-rw-r--r--source3/smbd/ipc.c9
-rw-r--r--source3/smbd/notify.c2
-rw-r--r--source3/smbd/nttrans.c8
-rw-r--r--source3/smbd/oplock.c9
-rw-r--r--source3/smbd/perfcount.c192
-rw-r--r--source3/smbd/pipes.c3
-rw-r--r--source3/smbd/process.c61
-rw-r--r--source3/smbd/reply.c10
-rw-r--r--source3/smbd/trans2.c5
11 files changed, 278 insertions, 35 deletions
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index 64d512d675..75ce07d41a 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -301,7 +301,8 @@ bool schedule_aio_write_and_X(connection_struct *conn,
SSVAL(aio_ex->outbuf,smb_vwv4,(numtowrite>>16)&1);
show_msg(aio_ex->outbuf);
if (!srv_send_smb(smbd_server_fd(),aio_ex->outbuf,
- IS_CONN_ENCRYPTED(fsp->conn))) {
+ IS_CONN_ENCRYPTED(fsp->conn),
+ &req->pcd)) {
exit_server_cleanly("handle_aio_write: srv_send_smb "
"failed.");
}
@@ -375,7 +376,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
smb_setlen(outbuf,outsize - 4);
show_msg(outbuf);
if (!srv_send_smb(smbd_server_fd(),outbuf,
- IS_CONN_ENCRYPTED(aio_ex->fsp->conn))) {
+ IS_CONN_ENCRYPTED(aio_ex->fsp->conn), NULL)) {
exit_server_cleanly("handle_aio_read_complete: srv_send_smb "
"failed.");
}
@@ -472,7 +473,8 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
}
show_msg(outbuf);
- if (!srv_send_smb(smbd_server_fd(),outbuf,IS_CONN_ENCRYPTED(fsp->conn))) {
+ if (!srv_send_smb(smbd_server_fd(),outbuf,IS_CONN_ENCRYPTED(fsp->conn),
+ NULL)) {
exit_server_cleanly("handle_aio_write: srv_send_smb failed.");
}
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index ac1ff00858..659ef700cb 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -192,6 +192,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
return False;
}
+ SMB_PERFCOUNT_DEFER_OP(&req->pcd, &req->pcd);
blr->req = talloc_move(blr, &req);
DLIST_ADD_END(blocking_lock_queue, blr, blocking_lock_record *);
@@ -266,7 +267,7 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat
reply_nterror(blr->req, status);
if (!srv_send_smb(smbd_server_fd(), (char *)blr->req->outbuf,
- blr->req->encrypted)) {
+ blr->req->encrypted, NULL)) {
exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed.");
}
TALLOC_FREE(blr->req->outbuf);
@@ -347,7 +348,8 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status
if (!srv_send_smb(smbd_server_fd(),
(char *)blr->req->outbuf,
- IS_CONN_ENCRYPTED(blr->fsp->conn))) {
+ IS_CONN_ENCRYPTED(blr->fsp->conn),
+ NULL)) {
exit_server_cleanly("blocking_lock_reply_error: "
"srv_send_smb failed.");
}
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 9c7528dfa7..d18b5debe0 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -134,7 +134,7 @@ void send_trans_reply(connection_struct *conn,
show_msg((char *)req->outbuf);
if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
- IS_CONN_ENCRYPTED(conn))) {
+ IS_CONN_ENCRYPTED(conn), &req->pcd)) {
exit_server_cleanly("send_trans_reply: srv_send_smb failed.");
}
@@ -190,7 +190,7 @@ void send_trans_reply(connection_struct *conn,
show_msg((char *)req->outbuf);
if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
- IS_CONN_ENCRYPTED(conn)))
+ IS_CONN_ENCRYPTED(conn), &req->pcd))
exit_server_cleanly("send_trans_reply: srv_send_smb "
"failed.");
@@ -298,7 +298,8 @@ static void api_dcerpc_cmd_write_done(struct async_req *subreq)
send:
if (!srv_send_smb(
smbd_server_fd(), (char *)req->outbuf,
- IS_CONN_ENCRYPTED(req->conn) || req->encrypted)) {
+ IS_CONN_ENCRYPTED(req->conn) || req->encrypted,
+ &req->pcd)) {
exit_server_cleanly("construct_reply: srv_send_smb failed.");
}
TALLOC_FREE(req);
@@ -324,7 +325,7 @@ static void api_dcerpc_cmd_read_done(struct async_req *subreq)
if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
IS_CONN_ENCRYPTED(req->conn)
- ||req->encrypted)) {
+ ||req->encrypted, &req->pcd)) {
exit_server_cleanly("construct_reply: srv_send_smb "
"failed.");
}
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index 7ffe62058c..1d4f5e8c5b 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -144,7 +144,7 @@ static void change_notify_reply_packet(connection_struct *conn,
show_msg((char *)req->outbuf);
if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
- req->encrypted)) {
+ req->encrypted, &req->pcd)) {
exit_server_cleanly("change_notify_reply_packet: srv_send_smb "
"failed.");
}
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 0ad4df6e90..ad2366efae 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -230,7 +230,8 @@ void send_nt_replies(connection_struct *conn,
show_msg((char *)req->outbuf);
if (!srv_send_smb(smbd_server_fd(),
(char *)req->outbuf,
- IS_CONN_ENCRYPTED(conn))) {
+ IS_CONN_ENCRYPTED(conn),
+ &req->pcd)) {
exit_server_cleanly("send_nt_replies: srv_send_smb failed.");
}
@@ -1823,6 +1824,8 @@ static void call_nt_transact_ioctl(connection_struct *conn,
because I don't want to break anything... --metze
FSP_BELONGS_CONN(fsp,conn);*/
+ SMB_PERFCOUNT_SET_IOCTL(&req->pcd, function);
+
switch (function) {
case FSCTL_SET_SPARSE:
/* pretend this succeeded - tho strictly we should
@@ -2489,6 +2492,9 @@ static void handle_nttrans(connection_struct *conn,
SSVAL(req->inbuf,smb_flg2,req->flags2);
}
+
+ SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
+
/* Now we must call the relevant NT_TRANS function */
switch(state->call) {
case NT_TRANSACT_CREATE:
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 788d2f7238..3dac674c17 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -406,7 +406,8 @@ static void process_oplock_async_level2_break_message(struct messaging_context *
show_msg(break_msg);
if (!srv_send_smb(smbd_server_fd(),
break_msg,
- IS_CONN_ENCRYPTED(fsp->conn))) {
+ IS_CONN_ENCRYPTED(fsp->conn),
+ NULL)) {
exit_server_cleanly("oplock_break: srv_send_smb failed.");
}
@@ -513,7 +514,8 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
show_msg(break_msg);
if (!srv_send_smb(smbd_server_fd(),
break_msg,
- IS_CONN_ENCRYPTED(fsp->conn))) {
+ IS_CONN_ENCRYPTED(fsp->conn),
+ NULL)) {
exit_server_cleanly("oplock_break: srv_send_smb failed.");
}
@@ -592,7 +594,8 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx,
show_msg(break_msg);
if (!srv_send_smb(smbd_server_fd(),
break_msg,
- IS_CONN_ENCRYPTED(fsp->conn))) {
+ IS_CONN_ENCRYPTED(fsp->conn),
+ NULL)) {
exit_server_cleanly("oplock_break: srv_send_smb failed.");
}
diff --git a/source3/smbd/perfcount.c b/source3/smbd/perfcount.c
new file mode 100644
index 0000000000..0ad706c46d
--- /dev/null
+++ b/source3/smbd/perfcount.c
@@ -0,0 +1,192 @@
+/*
+ Unix SMB/Netbios implementation.
+ Perfcounter initialization and support functions
+ Copyright (C) Todd Stecher 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "includes.h"
+
+struct smb_perfcount_handlers *g_smb_perfcount_handlers = NULL;
+
+struct smb_perfcount_module {
+ char *name;
+ struct smb_perfcount_handlers *handlers;
+ struct smb_perfcount_module *prev, *next;
+};
+
+struct smb_perfcount_module *modules = NULL;
+
+
+/*
+ * a module is registered before it is actually loaded - keep a list
+ *
+ * @todo - currently perfcount modules are globally configured, so
+ * building the list is not strictly required.
+ * However, its a proven concept in VFS, and is here to allow a
+ * move to eventual per-service perfcount configuration.
+ *
+ * Note many pre-connection statistics are interesting
+ * (e.g. before binding to an individual share).
+ *
+ */
+static struct smb_perfcount_module *smb_perfcount_find_module(const char *name)
+{
+ struct smb_perfcount_module *entry = modules;
+
+ while (entry) {
+ if (strcmp(entry->name, name)==0)
+ return entry;
+
+ entry = entry->next;
+ }
+
+ return NULL;
+}
+NTSTATUS smb_register_perfcounter(int interface_version, const char *name,
+ const struct smb_perfcount_handlers *handlers)
+{
+ struct smb_perfcount_module *entry = modules;
+
+ if ((interface_version != SMB_PERFCOUNTER_INTERFACE_VERSION)) {
+ DEBUG(0, ("Failed to register perfcount module.\n"
+ "The module was compiled against "
+ "SMB_PERFCOUNTER_INTERFACE_VERSION %d,\n"
+ "current SMB_PERFCOUNTER_INTERFACE_VERSION is %d.\n"
+ "Please recompile against the current Samba Version!\n",
+ interface_version, SMB_PERFCOUNTER_INTERFACE_VERSION));
+ return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ if (!name || !name[0] || !handlers) {
+ DEBUG(0,("smb_register_perfcounter() called with NULL pointer "
+ "or empty name!\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (smb_perfcount_find_module(name)) {
+ DEBUG(0,("Perfcount Module %s already loaded!\n", name));
+ return NT_STATUS_OK;
+ }
+
+ entry = SMB_XMALLOC_P(struct smb_perfcount_module);
+ entry->name = smb_xstrdup(name);
+ entry->handlers = (struct smb_perfcount_handlers*) handlers;
+
+ DLIST_ADD(modules, entry);
+ DEBUG(0, ("Successfully added perfcounter module '%s'\n", name));
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ initialise smb perf counters
+ ****************************************************************************/
+bool smb_load_perfcount_module(const char *name)
+{
+ char *module_path = NULL;
+ char *module_name = NULL;
+ char *module_param = NULL, *p;
+
+ const struct smb_perfcount_module *entry;
+
+ DEBUG(3, ("Initialising perfcounter module [%s]\n", name));
+
+ if (g_smb_perfcount_handlers) {
+ DEBUG(0,("Only 1 perfcount handler may be registered in "
+ "smb.conf\n"));
+ return true;
+ }
+
+ module_path = smb_xstrdup(name);
+
+ p = strchr_m(module_path, ':');
+
+ if (p) {
+ *p = 0;
+ module_param = p+1;
+ trim_char(module_param, ' ', ' ');
+ }
+
+ trim_char(module_path, ' ', ' ');
+
+ module_name = smb_xstrdup(module_path);
+
+ if (module_name[0] == '/') {
+
+ /*
+ * Extract the module name from the path. Just use the base
+ * name of the last path component.
+ */
+
+ SAFE_FREE(module_name);
+ module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
+
+ p = strchr_m(module_name, '.');
+
+ if (p != NULL) {
+ *p = '\0';
+ }
+ }
+
+ /* load the perfcounter module */
+ if((entry = smb_perfcount_find_module(module_name)) ||
+ (NT_STATUS_IS_OK(smb_probe_module("perfcount", module_path)) &&
+ (entry = smb_perfcount_find_module(module_name)))) {
+
+ DEBUG(0,("Successfully loaded perfcounter module [%s] \n", name));
+ } else {
+ DEBUG(0,("Can't find a perfcounter module [%s]\n",name));
+ goto fail;
+ }
+
+ g_smb_perfcount_handlers = entry->handlers;
+
+ SAFE_FREE(module_path);
+ SAFE_FREE(module_name);
+ return True;
+
+ fail:
+ SAFE_FREE(module_path);
+ SAFE_FREE(module_name);
+ return False;
+}
+
+void smb_init_perfcount_data(struct smb_perfcount_data *pcd)
+{
+
+ ZERO_STRUCTP(pcd);
+ pcd->handlers = g_smb_perfcount_handlers;
+}
+
+bool smb_perfcount_init(void)
+{
+ char *perfcount_object;
+
+ perfcount_object = lp_smb_perfcount_module();
+
+ /* don't init */
+ if (!perfcount_object || !perfcount_object[0])
+ return True;
+
+ if (!smb_load_perfcount_module(perfcount_object)) {
+ DEBUG(0, ("smbd_load_percount_module failed for %s\n",
+ perfcount_object));
+ return False;
+ }
+
+
+ return True;
+}
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index f287adc92d..6fd4031f3d 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -216,7 +216,8 @@ static void pipe_write_done(struct async_req *subreq)
send:
if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
- IS_CONN_ENCRYPTED(req->conn)||req->encrypted)) {
+ IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
+ &req->pcd)) {
exit_server_cleanly("construct_reply: srv_send_smb failed.");
}
TALLOC_FREE(req);
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 8539e04bd5..1262d01840 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -32,9 +32,10 @@ static void construct_reply_common(struct smb_request *req, const char *inbuf,
Send an smb to a fd.
****************************************************************************/
-bool srv_send_smb(int fd, char *buffer, bool do_encrypt)
+bool srv_send_smb(int fd, char *buffer, bool do_encrypt,
+ struct smb_perfcount_data *pcd)
{
- size_t len;
+ size_t len = 0;
size_t nwritten=0;
ssize_t ret;
char *buf_out = buffer;
@@ -48,7 +49,7 @@ bool srv_send_smb(int fd, char *buffer, bool do_encrypt)
DEBUG(0, ("send_smb: SMB encryption failed "
"on outgoing packet! Error %s\n",
nt_errstr(status) ));
- return false;
+ goto out;
}
}
@@ -60,12 +61,15 @@ bool srv_send_smb(int fd, char *buffer, bool do_encrypt)
DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
(int)len,(int)ret, strerror(errno) ));
srv_free_enc_buffer(buf_out);
- return false;
+ goto out;
}
nwritten += ret;
}
+ SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
srv_free_enc_buffer(buf_out);
+out:
+ SMB_PERFCOUNT_END(pcd);
return true;
}
@@ -373,6 +377,7 @@ void init_smb_request(struct smb_request *req,
req->conn = conn_find(req->tid);
req->chain_fsp = NULL;
req->chain_outbuf = NULL;
+ smb_init_perfcount_data(&req->pcd);
/* Ensure we have at least wct words and 2 bytes of bcc. */
if (smb_size + req->wct*2 > req_size) {
@@ -390,12 +395,13 @@ void init_smb_request(struct smb_request *req,
(unsigned int)req_size));
exit_server_cleanly("Invalid SMB request");
}
+
req->outbuf = NULL;
}
static void process_smb(struct smbd_server_connection *conn,
uint8_t *inbuf, size_t nread, size_t unread_bytes,
- bool encrypted);
+ bool encrypted, struct smb_perfcount_data *deferred_pcd);
static void smbd_deferred_open_timer(struct event_context *ev,
struct timed_event *te,
@@ -421,7 +427,7 @@ static void smbd_deferred_open_timer(struct event_context *ev,
process_smb(smbd_server_conn, inbuf,
msg->buf.length, 0,
- msg->encrypted);
+ msg->encrypted, &msg->pcd);
}
/****************************************************************************
@@ -453,6 +459,7 @@ static bool push_queued_message(struct smb_request *req,
msg->request_time = request_time;
msg->encrypted = req->encrypted;
+ SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
if (private_data) {
msg->private_data = data_blob_talloc(msg, private_data,
@@ -1354,7 +1361,9 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in
Construct a reply to the incoming packet.
****************************************************************************/
-static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool encrypted)
+static void construct_reply(char *inbuf, int size, size_t unread_bytes,
+ bool encrypted,
+ struct smb_perfcount_data *deferred_pcd)
{
connection_struct *conn;
struct smb_request *req;
@@ -1362,9 +1371,19 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool enc
if (!(req = talloc(talloc_tos(), struct smb_request))) {
smb_panic("could not allocate smb_request");
}
+
init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
+ /* we popped this message off the queue - keep original perf data */
+ if (deferred_pcd)
+ req->pcd = *deferred_pcd;
+ else {
+ SMB_PERFCOUNT_START(&req->pcd);
+ SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
+ SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
+ }
+
conn = switch_message(req->cmd, req, size);
if (req->unread_bytes) {
@@ -1386,7 +1405,8 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool enc
if (!srv_send_smb(smbd_server_fd(),
(char *)req->outbuf,
- IS_CONN_ENCRYPTED(conn)||req->encrypted)) {
+ IS_CONN_ENCRYPTED(conn)||req->encrypted,
+ &req->pcd)) {
exit_server_cleanly("construct_reply: srv_send_smb failed.");
}
@@ -1398,10 +1418,9 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool enc
/****************************************************************************
Process an smb from the client
****************************************************************************/
-
static void process_smb(struct smbd_server_connection *conn,
uint8_t *inbuf, size_t nread, size_t unread_bytes,
- bool encrypted)
+ bool encrypted, struct smb_perfcount_data *deferred_pcd)
{
int msg_type = CVAL(inbuf,0);
@@ -1423,8 +1442,7 @@ static void process_smb(struct smbd_server_connection *conn,
show_msg((char *)inbuf);
- construct_reply((char *)inbuf,nread,unread_bytes,encrypted);
-
+ construct_reply((char *)inbuf,nread,unread_bytes,encrypted,deferred_pcd);
trans_num++;
done:
@@ -1617,16 +1635,24 @@ void chain_reply(struct smb_request *req)
*/
smb_setlen((char *)(req->chain_outbuf),
talloc_get_size(req->chain_outbuf) - 4);
+
if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
IS_CONN_ENCRYPTED(req->conn)
- ||req->encrypted)) {
+ ||req->encrypted,
+ &req->pcd)) {
exit_server_cleanly("chain_reply: srv_send_smb "
"failed.");
}
TALLOC_FREE(req);
+
return;
}
+ /* add a new perfcounter for this element of chain */
+ SMB_PERFCOUNT_ADD(&req->pcd);
+ SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
+ SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
+
/*
* Check if the client tries to fool us. The request so far uses the
* space to the end of the byte buffer in the request just
@@ -1735,7 +1761,8 @@ void chain_reply(struct smb_request *req)
show_msg((char *)(req->chain_outbuf));
if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
- IS_CONN_ENCRYPTED(req->conn)||req->encrypted)) {
+ IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
+ &req->pcd)) {
exit_server_cleanly("construct_reply: srv_send_smb failed.");
}
TALLOC_FREE(req);
@@ -1823,7 +1850,7 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c
}
process:
- process_smb(conn, inbuf, inbuf_len, unread_bytes, encrypted);
+ process_smb(conn, inbuf, inbuf_len, unread_bytes, encrypted, NULL);
}
static void smbd_server_connection_handler(struct event_context *ev,
@@ -1988,7 +2015,7 @@ void smbd_process(void)
unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
DEBUG( 1, ("Connection denied from %s\n",
client_addr(get_client_fd(),addr,sizeof(addr)) ) );
- (void)srv_send_smb(smbd_server_fd(),(char *)buf,false);
+ (void)srv_send_smb(smbd_server_fd(),(char *)buf,false, NULL);
exit_server_cleanly("connection denied");
}
@@ -1996,6 +2023,8 @@ void smbd_process(void)
init_modules();
+ smb_perfcount_init();
+
if (!init_account_policy()) {
exit_server("Could not open account policy tdb.\n");
}
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index bb5fadd465..60e2e5dc7a 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -492,7 +492,7 @@ void reply_special(char *inbuf)
DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n",
msg_type, msg_flags));
- srv_send_smb(smbd_server_fd(), outbuf, false);
+ srv_send_smb(smbd_server_fd(), outbuf, false, NULL);
return;
}
@@ -3293,6 +3293,8 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
/* No outbuf here means successful sendfile. */
TALLOC_FREE(req->outbuf);
+ SMB_PERFCOUNT_SET_MSGLEN_OUT(&req->pcd, nread);
+ SMB_PERFCOUNT_END(&req->pcd);
return;
}
#endif
@@ -3590,7 +3592,8 @@ void reply_writebraw(struct smb_request *req)
show_msg(buf);
if (!srv_send_smb(smbd_server_fd(),
buf,
- IS_CONN_ENCRYPTED(conn))) {
+ IS_CONN_ENCRYPTED(conn),
+ &req->pcd)) {
exit_server_cleanly("reply_writebraw: srv_send_smb "
"failed.");
}
@@ -4647,7 +4650,8 @@ void reply_echo(struct smb_request *req)
show_msg((char *)req->outbuf);
if (!srv_send_smb(smbd_server_fd(),
(char *)req->outbuf,
- IS_CONN_ENCRYPTED(conn)||req->encrypted))
+ IS_CONN_ENCRYPTED(conn)||req->encrypted,
+ &req->pcd))
exit_server_cleanly("reply_echo: srv_send_smb failed.");
}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 6c082a8273..6a6e59a581 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -832,7 +832,8 @@ void send_trans2_replies(connection_struct *conn,
show_msg((char *)req->outbuf);
if (!srv_send_smb(smbd_server_fd(),
(char *)req->outbuf,
- IS_CONN_ENCRYPTED(conn)))
+ IS_CONN_ENCRYPTED(conn),
+ &req->pcd))
exit_server_cleanly("send_trans2_replies: srv_send_smb failed.");
TALLOC_FREE(req->outbuf);
@@ -7468,6 +7469,8 @@ static void handle_trans2(connection_struct *conn, struct smb_request *req,
}
}
+ SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
+
/* Now we must call the relevant TRANS2 function */
switch(state->call) {
case TRANSACT2_OPEN: