chore: comment cleanup pass ahead of open-sourcing
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:
@@ -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)) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user