Public Access
S1 #11: bytes read and written, counted per network service
A Counted<> wrapper around the network clients adds what goes through their buffer read and write to a per-service counter (IRC, Gemini, Debug Console, Updates); the single-byte calls and print() end up there, so each byte counts once. `net` prints the totals. For TLS it's the plain text the service sees. Checked on the device: a Gemini fetch counts 164,986 in (a 164,970-byte page and its 16-byte header) and 42 out (the URL and CRLF). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
+10
-2
@@ -19,6 +19,7 @@
|
||||
#include "event_bus.h"
|
||||
#include "file_receiver.h"
|
||||
#include "ipv4.h"
|
||||
#include "traffic.h"
|
||||
#include "key_mapper.h"
|
||||
#include "platform/console.h"
|
||||
#include "platform/crash_report.h"
|
||||
@@ -383,7 +384,7 @@ static void ipTrialStep() {
|
||||
|
||||
static const char* const kHelp =
|
||||
"info firmware, uptime, memory, Wi-Fi, app slots\n"
|
||||
"tasks FreeRTOS tasks: state, priority, free stack, CPU\n"
|
||||
"tasks FreeRTOS tasks: state, priority, free stack, CPU\n" "net bytes each network service has read and written since boot\n"
|
||||
"reboot restart\n"
|
||||
"boot other restart into the other app slot (manual Rollback)\n"
|
||||
"log level <0-5> ESP-IDF log level (0 none ... 5 verbose)\n"
|
||||
@@ -415,7 +416,7 @@ static const char* const kHelp =
|
||||
|
||||
// Commands that only touch what Safe Mode starts.
|
||||
static bool safeModeCommand(const String& line) {
|
||||
return line == "help" || line == "info" || line == "tasks" || line == "reboot" || line == "boot other" ||
|
||||
return line == "help" || line == "info" || line == "tasks" || line == "net" || line == "reboot" || line == "boot other" ||
|
||||
line.startsWith("log level ") || line.startsWith("crash") || line.startsWith("coredump") ||
|
||||
line == "wifi status" || line.startsWith("wifi add ");
|
||||
}
|
||||
@@ -433,6 +434,13 @@ static void runCommand(String line) {
|
||||
system_info::printSlots(console, nvs);
|
||||
}
|
||||
if (line == "tasks") system_info::printTasks(console);
|
||||
if (line == "net") { // bytes each service has read and written since boot (S1, Q121)
|
||||
for (int i = 0; i < static_cast<int>(net::User::Count); i++) {
|
||||
net::Traffic t = net::traffic(static_cast<net::User>(i));
|
||||
console.printf("net: %-14s in %10lu out %10lu\n", net::userName(static_cast<net::User>(i)), (unsigned long)t.in,
|
||||
(unsigned long)t.out);
|
||||
}
|
||||
}
|
||||
if (line == "reboot") {
|
||||
console.println("restarting");
|
||||
delay(300);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "traffic.h"
|
||||
|
||||
namespace roro {
|
||||
|
||||
// A NetworkClient (or NetworkClientSecure) that adds what it reads and writes to its service's
|
||||
// traffic counters (S1, Q121). Only the two buffer calls are overridden: the single-byte ones,
|
||||
// print() and printf() all go through them, so every byte is counted once.
|
||||
template <class Base>
|
||||
class Counted : public Base {
|
||||
public:
|
||||
explicit Counted(net::User user) : user_(user) {}
|
||||
Counted(const Base& accepted, net::User user) : Base(accepted), user_(user) {}
|
||||
|
||||
// Overriding the buffer calls hides the single-byte ones; these put them back. They end up in
|
||||
// the buffer calls below, where the counting happens.
|
||||
int read() override { return Base::read(); }
|
||||
size_t write(uint8_t byte) override { return Base::write(byte); }
|
||||
|
||||
size_t write(const uint8_t* buf, size_t size) override {
|
||||
size_t n = Base::write(buf, size);
|
||||
net::sent(user_, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
int read(uint8_t* buf, size_t size) override {
|
||||
int n = Base::read(buf, size);
|
||||
if (n > 0) net::received(user_, static_cast<size_t>(n));
|
||||
return n;
|
||||
}
|
||||
|
||||
private:
|
||||
net::User user_;
|
||||
};
|
||||
|
||||
} // namespace roro
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "file_receiver.h"
|
||||
#include "sha256.h"
|
||||
#include "platform/console.h"
|
||||
#include "platform/counted_client.h"
|
||||
#include "sd_fault.h"
|
||||
#include "version.h"
|
||||
|
||||
@@ -110,7 +111,7 @@ void DebugConsole::listen() {
|
||||
listening = false;
|
||||
}
|
||||
if (listening) {
|
||||
NetworkClient client = server.accept();
|
||||
Counted<NetworkClient> client(server.accept(), net::User::DebugConsole);
|
||||
if (client) {
|
||||
client.setNoDelay(true);
|
||||
if (authenticate(client)) serve(client);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "gemtext.h"
|
||||
#include "platform/console.h"
|
||||
#include "sha256.h"
|
||||
#include "platform/counted_client.h"
|
||||
#include "storage_paths.h"
|
||||
|
||||
namespace roro {
|
||||
@@ -544,7 +545,7 @@ void GeminiService::fetchOne(const std::string& url, GeminiPage& page, bool load
|
||||
auto track = [this]() { lowest_ = std::min<size_t>(lowest_, esp_get_free_heap_size()); };
|
||||
|
||||
size_t freeBefore = esp_get_free_heap_size(); // what's left once the connection closes again
|
||||
NetworkClientSecure tls;
|
||||
Counted<NetworkClientSecure> tls(net::User::Gemini);
|
||||
tls.setInsecure(); // trust on first use: the pinned fingerprint is what counts (Q71)
|
||||
tls.setTimeout(15);
|
||||
if (!tls.connect(u.host.c_str(), u.portOrDefault())) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <NetworkClientSecure.h>
|
||||
#include "platform/counted_client.h"
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/semphr.h>
|
||||
|
||||
@@ -75,8 +76,8 @@ class IrcService : public Service {
|
||||
std::unique_ptr<IrcSession> session_;
|
||||
SemaphoreHandle_t lock_ = nullptr;
|
||||
TaskHandle_t task_ = nullptr;
|
||||
NetworkClientSecure tlsClient_;
|
||||
NetworkClient plainClient_;
|
||||
Counted<NetworkClientSecure> tlsClient_{net::User::Irc}; // counted for the System App (S1, Q121)
|
||||
Counted<NetworkClient> plainClient_{net::User::Irc};
|
||||
NetworkClient* conn_ = &tlsClient_; // whichever the config asks for
|
||||
ReconnectPolicy backoff_;
|
||||
std::string partial_;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "update_service.h"
|
||||
#include "platform/counted_client.h"
|
||||
|
||||
#include <SD.h>
|
||||
#include <WiFi.h>
|
||||
@@ -208,7 +209,7 @@ void UpdateService::listen() {
|
||||
}
|
||||
}
|
||||
if (listening && phase_ == Phase::Idle) {
|
||||
NetworkClient client = server.accept();
|
||||
Counted<NetworkClient> client(server.accept(), net::User::Updates);
|
||||
if (client) {
|
||||
client.setNoDelay(true);
|
||||
NetSource src(client);
|
||||
|
||||
Reference in New Issue
Block a user