aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/channels.c34
-rw-r--r--src/channels1.c3
-rw-r--r--src/packet.c8
-rw-r--r--src/session.c39
-rw-r--r--src/socket.c6
5 files changed, 90 insertions, 0 deletions
diff --git a/src/channels.c b/src/channels.c
index b6f59f5f..7a72cfe4 100644
--- a/src/channels.c
+++ b/src/channels.c
@@ -555,6 +555,9 @@ SSH_PACKET_CALLBACK(channel_rcv_data){
is_stderr,
channel->callbacks->userdata);
if(rest > 0) {
+ if (channel->counter != NULL) {
+ channel->counter->in_bytes += rest;
+ }
buffer_pass_bytes(buf, rest);
}
if (channel->local_window + buffer_get_rest_len(buf) < WINDOWLIMIT) {
@@ -1406,6 +1409,9 @@ static int channel_write_common(ssh_channel channel,
channel->remote_window -= effectivelen;
len -= effectivelen;
data = ((uint8_t*)data + effectivelen);
+ if (channel->counter != NULL) {
+ channel->counter->out_bytes += effectivelen;
+ }
}
/* it's a good idea to flush the socket now */
@@ -2843,6 +2849,9 @@ int ssh_channel_read_timeout(ssh_channel channel,
len = (len > count ? count : len);
memcpy(dest, buffer_get_rest(stdbuf), len);
buffer_pass_bytes(stdbuf,len);
+ if (channel->counter != NULL) {
+ channel->counter->in_bytes += len;
+ }
/* Authorize some buffering while userapp is busy */
if (channel->local_window < WINDOWLIMIT) {
if (grow_window(session, channel, 0) < 0) {
@@ -3269,6 +3278,31 @@ int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans,
return 0;
}
+/**
+ * @brief Set the channel data counter.
+ *
+ * @code
+ * struct ssh_counter_struct counter = {
+ * .in_bytes = 0,
+ * .out_bytes = 0,
+ * .in_packets = 0,
+ * .out_packets = 0
+ * };
+ *
+ * ssh_channel_set_counter(channel, &counter);
+ * @endcode
+ *
+ * @param[in] channel The SSH channel.
+ *
+ * @param[in] counter Counter for bytes handled by the channel.
+ */
+void ssh_channel_set_counter(ssh_channel channel,
+ ssh_counter counter) {
+ if (channel != NULL) {
+ channel->counter = counter;
+ }
+}
+
#if WITH_SERVER
/**
* @brief Blocking write on a channel stderr.
diff --git a/src/channels1.c b/src/channels1.c
index 2b307408..4d82c636 100644
--- a/src/channels1.c
+++ b/src/channels1.c
@@ -367,6 +367,9 @@ int channel_write1(ssh_channel channel, const void *data, int len) {
return -1;
}
ssh_handle_packets(session, SSH_TIMEOUT_NONBLOCKING);
+ if (channel->counter != NULL) {
+ channel->counter->out_bytes += effectivelen;
+ }
}
if (ssh_blocking_flush(session,SSH_TIMEOUT_USER) == SSH_ERROR)
return -1;
diff --git a/src/packet.c b/src/packet.c
index 4aed2fac..71ba40d1 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -311,6 +311,10 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
#endif /* WITH_ZLIB */
payloadsize = buffer_get_rest_len(session->in_buffer);
session->recv_seq++;
+ if (session->raw_counter != NULL) {
+ session->raw_counter->in_bytes += payloadsize;
+ session->raw_counter->in_packets++;
+ }
/*
* We don't want to rewrite a new packet while still executing the
@@ -560,6 +564,10 @@ static int packet_send2(ssh_session session) {
rc = ssh_packet_write(session);
session->send_seq++;
+ if (session->raw_counter != NULL) {
+ session->raw_counter->out_bytes += payloadsize;
+ session->raw_counter->out_packets++;
+ }
SSH_LOG(SSH_LOG_PACKET,
"packet: wrote [len=%d,padding=%hhd,comp=%d,payload=%d]",
diff --git a/src/session.c b/src/session.c
index 93c047f9..3f22f111 100644
--- a/src/session.c
+++ b/src/session.c
@@ -831,6 +831,45 @@ error:
return SSH_ERROR;
}
+ /**
+ * @brief Set the session data counters.
+ *
+ * This functions sets the counter structures to be used to calculate data
+ * which comes in and goes out through the session at different levels.
+ *
+ * @code
+ * struct ssh_counter_struct scounter = {
+ * .in_bytes = 0,
+ * .out_bytes = 0,
+ * .in_packets = 0,
+ * .out_packets = 0
+ * };
+ *
+ * struct ssh_counter_struct rcounter = {
+ * .in_bytes = 0,
+ * .out_bytes = 0,
+ * .in_packets = 0,
+ * .out_packets = 0
+ * };
+ *
+ * ssh_set_counters(session, &scounter, &rcounter);
+ * @endcode
+ *
+ * @param[in] session The SSH session.
+ *
+ * @param[in] scounter Counter for byte data handled by the session sockets.
+ *
+ * @param[in] rcounter Counter for byte and packet data handled by the session,
+ * prior compression and SSH overhead.
+ */
+void ssh_set_counters(ssh_session session, ssh_counter scounter,
+ ssh_counter rcounter) {
+ if (session != NULL) {
+ session->socket_counter = scounter;
+ session->raw_counter = rcounter;
+ }
+}
+
/** @} */
/* vim: set ts=4 sw=4 et cindent: */
diff --git a/src/socket.c b/src/socket.c
index 8f4c9b22..ab47b96a 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -280,6 +280,9 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd, int r
}
}
if(r>0){
+ if (s->session->socket_counter != NULL) {
+ s->session->socket_counter->in_bytes += r;
+ }
/* Bufferize the data and then call the callback */
r = ssh_buffer_add_data(s->in_buffer,buffer,r);
if (r < 0) {
@@ -659,6 +662,9 @@ int ssh_socket_nonblocking_flush(ssh_socket s) {
return SSH_ERROR;
}
buffer_pass_bytes(s->out_buffer, w);
+ if (s->session->socket_counter != NULL) {
+ s->session->socket_counter->out_bytes += w;
+ }
}
/* Is there some data pending? */