chore: comment cleanup pass ahead of open-sourcing
Some checks failed
Build Linux Binaries / linux/amd64 (push) Has been cancelled
Build Linux Binaries / linux/arm64 (push) Has been cancelled

Removes leftover debug scaffolding (stray Console.WriteLine/NSLog traces,
dead nick_buf_ptr, a no-op --print-config flag now implemented for real),
fixes stale/misleading comments (channel passwords are no longer a "future
M5+" feature, a wrong cross-reference, a stale TlsContext::close() mention,
an incomplete BanRecord::subject_type doc, and a smoke test pointing at a
build/m1-dev preset that no longer exists), strips internal M1-M5 milestone
jargon from comments now that the roadmap is done, trims comments that just
restated the following line, and consolidates a few "why" explanations that
were duplicated 2-3 times in the same file.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-03 10:20:18 +01:00
parent bda37ec27b
commit bba605401d
50 changed files with 229 additions and 331 deletions

View File

@@ -88,9 +88,8 @@ void ConnSession::on_frame(std::vector<uint8_t> frame) {
handle_ping(env.ping());
break;
case voicecat::v1::Envelope::kDisconnect:
// Client-initiated graceful disconnect (code=0). Falls through to close() which
// broadcasts UserEvent::LEFT — same as a TCP drop, but immediate (no reaper/EOF
// wait). Gated on Authenticated so a pre-auth stray Disconnect can't skip cleanup.
// See handle_client_disconnect for the close()/idempotency rationale. Gated on
// Authenticated so a pre-auth stray Disconnect can't skip cleanup.
if (st == State::Authenticated) handle_client_disconnect(env.disconnect());
break;
case voicecat::v1::Envelope::kLeaveChannel:
@@ -118,7 +117,7 @@ void ConnSession::on_frame(std::vector<uint8_t> frame) {
handle_unsubscribe_voice(env.request_id());
break;
// ── M5 moderation / admin ─────────────────────────────────────────────
// ── Moderation / admin ──────────────────────────────────────────────────
case voicecat::v1::Envelope::kKick:
if (st == State::Authenticated) handle_kick_request(env.request_id(), env.kick());
break;
@@ -203,7 +202,7 @@ void ConnSession::close() {
if (close_fn_) close_fn_();
}
// ── M2: media crypto ─────────────────────────────────────────────────────────
// ── Media crypto ───────────────────────────────────────────────────────────────
void ConnSession::set_media_crypto(
std::unique_ptr<voicecat::crypto::SodiumMediaCrypto> send,
@@ -223,7 +222,7 @@ voicecat::crypto::SodiumMediaCrypto* ConnSession::recv_crypto() {
return recv_crypto_.get();
}
// ── M2: UDP endpoint ─────────────────────────────────────────────────────────
// ── UDP endpoint ─────────────────────────────────────────────────────────────
void ConnSession::set_udp_endpoint(asio::ip::udp::endpoint ep) {
{
@@ -335,7 +334,7 @@ void ConnSession::finish_password_auth(const std::string& username,
// Argon2id runs on the worker pool (deliberately slow).
auto self = shared_from_this();
workers_->post([self, username, password, req_id] {
// M5: check username bans before verifying password.
// Check username bans before verifying password.
if (self->db_->ban_check("username", username)) {
auto env = make_env(req_id);
env.mutable_auth_result()->set_ok(false);
@@ -669,7 +668,7 @@ void ConnSession::handle_unsubscribe_voice(uint64_t req_id) {
}
}
// ── M5 handlers ──────────────────────────────────────────────────────────────
// ── Moderation & admin handlers ─────────────────────────────────────────────────
void ConnSession::handle_kick_request(uint64_t req_id, const voicecat::v1::KickRequest& msg) {
if (!is_admin() && !has_permission(&voicecat::v1::Permissions::can_kick)) {

View File

@@ -60,20 +60,20 @@ class ConnSession : public std::enable_shared_from_this<ConnSession> {
// close a session without making it a friend class.
void send_disconnect_and_close(uint32_t code, const std::string& reason);
// ── M2: media key injection (called from on_tls_ready) ───────────────────
// ── Media key injection (called from on_tls_ready) ────────────────────────
void set_media_crypto(std::unique_ptr<voicecat::crypto::SodiumMediaCrypto> send,
std::unique_ptr<voicecat::crypto::SodiumMediaCrypto> recv);
// ── M2: UDP endpoint (set by MediaRelay on UdpBinding) ────────────────────
// ── UDP endpoint (set by MediaRelay on UdpBinding) ────────────────────────
void set_udp_endpoint(asio::ip::udp::endpoint ep);
asio::ip::udp::endpoint udp_endpoint() const;
bool has_udp_endpoint() const { return has_udp_ep_.load(); }
// ── M2: media crypto access (for SFU relay) ──────────────────────────────
// ── Media crypto access (for SFU relay) ───────────────────────────────────
voicecat::crypto::SodiumMediaCrypto* send_crypto();
voicecat::crypto::SodiumMediaCrypto* recv_crypto();
// ── M2: UDP token (for binding) ───────────────────────────────────────────
// ── UDP token (for binding) ────────────────────────────────────────────────
const std::array<uint8_t, 16>& udp_token() const { return udp_token_; }
// ── Accessors ──────────────────────────────────────────────────────────────
@@ -107,7 +107,7 @@ class ConnSession : public std::enable_shared_from_this<ConnSession> {
void handle_subscribe_voice(uint64_t req_id);
void handle_unsubscribe_voice(uint64_t req_id);
// M5 handlers
// Moderation & admin handlers
void handle_kick_request(uint64_t req_id, const voicecat::v1::KickRequest& msg);
void handle_ban_request(uint64_t req_id, const voicecat::v1::BanRequest& msg);
void handle_set_permission(uint64_t req_id, const voicecat::v1::SetPermissionRequest& msg);
@@ -155,7 +155,7 @@ class ConnSession : public std::enable_shared_from_this<ConnSession> {
// The reaper (server.cpp) drops sessions whose last_seen is older than 45s.
std::atomic<int64_t> last_seen_ms_{0};
// M2 UDP / media
// UDP / media
std::array<uint8_t, 16> udp_token_{};
mutable std::mutex udp_ep_mu_;
asio::ip::udp::endpoint udp_ep_;
@@ -165,13 +165,13 @@ class ConnSession : public std::enable_shared_from_this<ConnSession> {
std::unique_ptr<voicecat::crypto::SodiumMediaCrypto> send_crypto_;
std::unique_ptr<voicecat::crypto::SodiumMediaCrypto> recv_crypto_;
// M2/M3: locally-announced streams. The server assigns the stream_id (unique per
// Locally-announced streams. The server assigns the stream_id (unique per
// session), so a per-session counter + the set of currently-active ids is enough to
// support multiple concurrent streams (MIC + SCREEN_AUDIO + AUX_DEVICE) per user.
uint32_t next_stream_id_{1};
std::vector<uint32_t> announced_stream_ids_;
// M5: permissions granted at auth time (server-side authority).
// Permissions granted at auth time (server-side authority).
voicecat::v1::Permissions permissions_;
// Voice-plane subscription. When false, the SFU relay excludes this session from the

View File

@@ -89,7 +89,6 @@ bool Database::open(std::string& error) {
}
bool Database::migrate(std::string& error) {
// Ensure server_meta row exists.
if (!exec("INSERT OR IGNORE INTO server_meta (key, value) VALUES ('schema_version', '1')",
error))
return false;
@@ -241,7 +240,6 @@ std::optional<Account> Database::authenticate(const std::string& username,
if (crypto_pwhash_str_verify(hash.c_str(), password.c_str(), password.size()) != 0)
return std::nullopt;
// Update last_login
int64_t now = now_unix();
sqlite3_stmt* upd = nullptr;
sqlite3_prepare_v2(db_, "UPDATE accounts SET last_login=? WHERE id=?", -1, &upd, nullptr);

View File

@@ -44,7 +44,7 @@ struct ChannelRecord {
// Persistent ban record.
struct BanRecord {
int64_t id{0};
std::string subject_type; // "user_id" or "ip"
std::string subject_type; // "user_id", "username", or "ip"
std::string subject; // the banned value
std::string reason;
int64_t expires_at{0}; // 0 = permanent

View File

@@ -68,10 +68,15 @@ int main(int argc, char** argv) {
}
}
if (print_config_only) {
std::printf("server_name = %s\n", cfg.server_name.c_str());
std::printf("data_dir = %s\n", cfg.data_dir.c_str());
std::printf("bind_port = %u\n", cfg.bind_port);
std::printf("allow_guests = %s\n", cfg.allow_guests ? "true" : "false");
return 0;
}
std::printf("[voicecat-server %s] starting\n", vc_version_string());
voicecat::server::Server server(cfg);
if (print_config_only) {
// run() currently just prints config; in M1 split this into a pure config dump.
}
return server.run();
}

View File

@@ -1,5 +1,5 @@
/*
* server/media_relay.h — UDP SFU relay for M2 voice.
* server/media_relay.h — UDP SFU relay for voice.
*
* Design: docs/architecture.md §5, docs/voice.md §2.
* Receives encrypted UDP voice frames from clients, decrypts+authenticates them,

View File

@@ -65,7 +65,7 @@ int Server::run() {
// ── Asio io_context ──────────────────────────────────────────────────────
asio::io_context io;
// ── UDP media relay (M2) ─────────────────────────────────────────────────
// ── UDP media relay ────────────────────────────────────────────────────────
auto media_relay = std::make_shared<MediaRelay>(io, registry);
// Control and media share one port number on TCP+UDP (docs/deployment.md): when media_port
// is left at 0, follow bind_port so a single forward rule covers both. If bind_port is also 0
@@ -116,7 +116,8 @@ int Server::run() {
auto tcp = std::make_shared<voicecat::net::TcpServerConn>(
std::move(sock), std::move(cbs), std::move(tls));
// Give session its send/close capability (weak_ptr avoids cycle)
// Give session its send/close capability (weak_ptr — see the shared_ptr/cycle
// note above).
std::weak_ptr<voicecat::net::TcpServerConn> weak_tcp = tcp;
session->set_io(
[weak_tcp](std::vector<uint8_t> frame) {

View File

@@ -18,7 +18,7 @@ struct Config {
std::string server_name = "VoiceCat Server";
std::string data_dir = "voicecat-data";
uint16_t bind_port = 8384; // 0 = let OS pick (useful for tests)
uint16_t media_port = 0; // M2 UDP media; 0 = follow bind_port (or OS-pick if that's 0)
uint16_t media_port = 0; // UDP media port; 0 = follow bind_port (or OS-pick if that's 0)
bool allow_guests = true;
// Called with the actual bound TCP port once the acceptor is ready.
std::function<void(uint16_t)> on_ready;

View File

@@ -274,7 +274,7 @@ namespace {
ue->set_kind(voicecat::v1::UserEvent::LEFT);
ue->mutable_user()->set_id(user_id);
ue->set_left_id(user_id);
ue->set_reason(reason); // M5 additive field
ue->set_reason(reason);
return env;
}
}
@@ -447,7 +447,7 @@ bool SessionRegistry::check_channel_password(uint32_t channel_id,
return db_->check_channel_password(channel_id, password);
}
// ── M2: UDP / media ───────────────────────────────────────────────────────────
// ── UDP / media ────────────────────────────────────────────────────────────────
void SessionRegistry::register_udp_token(const std::array<uint8_t, 16>& token,
uint64_t session_id) {

View File

@@ -2,7 +2,7 @@
* server/session_registry.h — In-memory session, channel, and user registry.
*
* Tracks all authenticated sessions, the channel tree, user<→>channel assignments,
* UDP endpoint bindings (M2), and SSRC<→>session mappings (M2).
* UDP endpoint bindings, and SSRC<→>session mappings.
* Protected by a shared_mutex (many readers, few writers). All methods are thread-safe.
*/
#ifndef VOICECAT_SERVER_SESSION_REGISTRY_H
@@ -144,7 +144,7 @@ class SessionRegistry {
// Check a channel password.
bool check_channel_password(uint32_t channel_id, const std::string& password) const;
// ── M2: UDP / media ────────────────────────────────────────────────────────
// ── UDP / media ────────────────────────────────────────────────────────────
// Register a session's UDP token (called at auth success).
void register_udp_token(const std::array<uint8_t, 16>& token, uint64_t session_id);
@@ -177,7 +177,7 @@ class SessionRegistry {
// Return the channel_id of a user (0 if not found).
uint32_t user_channel(uint32_t user_id) const;
// Return a channel's authoritative AudioConfig (M3 per-channel Opus tuning), or nullopt
// Return a channel's authoritative AudioConfig (per-channel Opus tuning), or nullopt
// if the channel doesn't exist. There is no per-id Channel getter today otherwise —
// channel_snapshot() copies every channel, which callers needing just one config should
// avoid.
@@ -199,7 +199,7 @@ class SessionRegistry {
std::unordered_map<uint32_t, ChannelEntry> channels_;
std::unordered_map<uint64_t, voicecat::v1::Permissions> session_permissions_;
// M2: token → session_id (populated at auth, cleared on disconnect)
// Token → session_id (populated at auth, cleared on disconnect)
struct TokenHash {
size_t operator()(const std::array<uint8_t, 16>& t) const {
// FNV-1a over 16 bytes
@@ -210,10 +210,10 @@ class SessionRegistry {
};
std::unordered_map<std::array<uint8_t, 16>, uint64_t, TokenHash> udp_tokens_;
// M2: UDP endpoint → session_id (populated after UDP binding packet arrives)
// UDP endpoint → session_id (populated after UDP binding packet arrives)
std::unordered_map<asio::ip::udp::endpoint, uint64_t, UdpEndpointHash> udp_endpoints_;
// M2: ssrc → session_id (populated when StreamAnnounce is processed)
// ssrc → session_id (populated when StreamAnnounce is processed)
std::unordered_map<uint32_t, uint64_t> ssrc_to_session_;
std::atomic<uint32_t> next_ssrc_{1};
};