Skip to content
API Documentation
BastionGuard™
bsc::service::DaemonService Class Reference

#include <DaemonService.hpp>

Classes

struct  CachedVerdict

Public Member Functions

 DaemonService (bsc::config::Config config)
void run ()
void stop ()

Private Member Functions

void scan_connections ()
bool desktop_allows_activity () const
void set_desktop_active (bool active)
void handle_proc_event (const bsc::netlink::ProcEvent &ev)
void heartbeat ()
void reload_rules ()
void reload_firewall ()
void handle_notification (const bsc::ui::NotificationEvent &ev)
bsc::netfilter::Decision decide_connection (bsc::model::Connection conn, bool realtime, bool allow_blocking_ask=true)
void persist_learned_rule (const bsc::model::Connection &conn, const bsc::rule::Rule &decision)
void remember_connection (const bsc::model::Connection &conn)
void enrich_from_recent_flows (bsc::model::Connection &conn)
void enrich_from_recent_processes (bsc::model::Connection &conn, std::chrono::milliseconds max_age=std::chrono::milliseconds(5000))
bool rules_changed () const
std::optional< CachedVerdict > verdict_lookup (const bsc::model::Connection &c) const
void verdict_store (const bsc::model::Connection &c, const bsc::rule::Rule &r)

Static Private Member Functions

static std::chrono::milliseconds parse_interval (const std::string &v, std::chrono::milliseconds def=std::chrono::seconds(5))
static std::string verdict_key (const bsc::model::Connection &c)

Private Attributes

bsc::config::Config config_
bsc::fw::Firewall firewall_
bsc::net::DnsResolver dns_
bsc::netlink::ProcEventMonitor proc_events_
bsc::net::SocketSnapshot net_
bsc::netfilter::NFQueue nfqueue_
bsc::proc::ProcMon proc_
bsc::rule::Loader rules_
bsc::stats::Statistics stats_
bsc::ui::UIClient ui_
bsc::task::TaskRunner tasks_
std::atomic_bool running_ {true}
std::mutex seen_mutex_
std::set< std::string > seen_
std::mutex rules_reload_mutex_
std::mutex flow_mutex_
std::unordered_map< std::string, std::pair< bsc::model::Connection, std::chrono::steady_clock::time_point > > recent_flows_
std::mutex verdict_cache_mutex_
std::unordered_map< std::string, CachedVerdict > verdict_cache_
std::atomic_bool is_asking_ {false}
std::atomic_bool desktop_active_ {false}
std::atomic_bool inactive_notice_logged_ {false}
std::filesystem::file_time_type rules_mtime_ {}
std::chrono::steady_clock::time_point start_time_ {std::chrono::steady_clock::now()}

Detailed Description

Definition at line 23 of file DaemonService.hpp.

Constructor & Destructor Documentation

◆ DaemonService()

bsc::service::DaemonService::DaemonService ( bsc::config::Config config)
explicit

Definition at line 77 of file DaemonService.cpp.

79 const auto aliases = std::filesystem::path(config_.rules.path).parent_path() / "network_aliases.json";
80 rules_.load_aliases(aliases.string());
83}
void load_aliases(const std::string &path)
Definition Rule.cpp:292
void load_directory(const std::string &dir)
Definition Rule.cpp:311
bsc::stats::Statistics stats_
bsc::config::Config config_
StatsOptions stats
Definition Config.hpp:60
RulesOptions rules
Definition Config.hpp:58
std::string firewall
Definition Config.hpp:51
ServerConfig server
Definition Config.hpp:57

References config_, firewall_, bsc::rule::Loader::load_aliases(), bsc::rule::Loader::load_directory(), bsc::config::Config::RulesOptions::path, bsc::config::Config::rules, rules_, rules_changed(), stats_, and ui_.

Referenced by rules_changed().

Member Function Documentation

◆ decide_connection()

bsc::netfilter::Decision bsc::service::DaemonService::decide_connection ( bsc::model::Connection conn,
bool realtime,
bool allow_blocking_ask = true )
private

Definition at line 544 of file DaemonService.cpp.

544 {
545 auto& log = bsc::logging::Logger::instance();
546
547 // Se il desktop non è attivo o la UI non è connessa, non fare lookup,
548 // reverse DNS, popup o scansioni costose: lascia passare e basta.
549 // Questo evita allarmi/attività di rete quando la sessione grafica è
550 // inattiva, bloccata o non ancora pronta.
552 bsc::netfilter::Decision d;
554 return d;
555 }
556
557 if (conn.process_id == 0 || conn.process_path.empty()) enrich_from_recent_flows(conn);
558 if (!has_process_identity(conn)) {
559 enrich_from_recent_processes(conn, std::chrono::milliseconds(2500));
560 }
561 if (!has_process_identity(conn)) {
562 enrich_from_recent_processes(conn, std::chrono::milliseconds(6000));
563 }
564 if (conn.process_id > 0) {
566 merge_process_info(conn, *p);
567 }
568 }
569 if (realtime && conn.process_id == 0 && conn.process_comm.empty() && conn.process_path.empty()) {
570 log.warning("Connessione senza processo risolto: uid=" + std::to_string(conn.user_id) +
571 " dst=" + conn.dst_ip + ":" + std::to_string(conn.dst_port));
572 }
573 if (conn.dst_host.empty()) {
574 conn.dst_host = dns_.reverse_lookup(conn.dst_ip);
575 if (!conn.dst_host.empty()) stats_.note_dns_response();
576 }
577
578 std::string action;
579 std::string rule_name;
580 std::string duration = config_.default_duration;
581 bool asked_ui = false;
582
583 // 1) Cache dei verdetti "always" dati dall'utente in questa sessione:
584 // se Firefox ha gia' avuto un "allow always" verso google.com:443,
585 // le prossime 50 connessioni non aprono popup.
586 if (auto cached = verdict_lookup(conn)) {
587 action = cached->action;
588 duration = cached->duration;
589 rule_name = "cache";
590 }
591 // 2) Regole JSON persistite (localhost, regole utente salvate)
592 else if (auto matched = rules_.find_match(conn)) {
593 action = matched->action;
594 duration = matched->duration;
595 rule_name = matched->name;
596 }
597 // 3) Chiedi all'utente solo fuori dal callback NFQUEUE.
598 // Il callback NFQUEUE deve restare veloce: se aspetta il popup per
599 // 15-30s, la coda kernel si riempie e gli eventi successivi sembrano
600 // "persi". NFQUEUE quindi applica cache/regole/default e la scansione
601 // periodica farà l'eventuale AskRule senza bloccare la coda pacchetti.
602 else if (config_.intercept_unknown && realtime && allow_blocking_ask) {
603 if (is_asking_.load()) {
604 log.debug("ask_rule gia' in volo, applico default_action=" +
605 config_.default_action + " per " + conn.process_path);
606 action = config_.default_action;
607 } else {
608 is_asking_ = true;
609 asked_ui = true;
610 log.info("AskRule: " + conn.protocol + " " + conn.process_path + " -> " +
611 (!conn.dst_host.empty() ? conn.dst_host : conn.dst_ip) +
612 ":" + std::to_string(conn.dst_port));
613 auto asked = ui_.ask_rule(conn);
614 is_asking_ = false;
615
616 if (asked) {
617 action = asked->action.empty() ? config_.default_action : asked->action;
618 duration = asked->duration.empty() ? config_.default_duration : asked->duration;
619 rule_name = asked->name;
620 asked->duration = duration;
621 asked->action = action;
622 log.info("AskRule risposta: action=" + action + ", duration=" + duration);
623 verdict_store(conn, *asked); // cache in-memory
624 persist_learned_rule(conn, *asked); // + eventuale save su disco
625 } else {
626 log.warning("AskRule senza risposta, uso default_action=" +
628 action = config_.default_action;
629 }
630 }
631 } else {
632 action = config_.default_action;
633 }
634
636 stats_.record(conn, action, rule_name);
637
638 // Non perdere più le connessioni "default": se la UI non ha già ricevuto
639 // un AskRule per questa connessione, invia sempre l'evento realtime.
640 // La UI aggiorna liste/mappa/statistiche senza dover aprire un popup.
641 if (realtime && !asked_ui && desktop_allows_activity()) {
642 log.info("PostAlert UI: action=" + action +
643 (rule_name.empty() ? std::string{} : ", rule=" + rule_name));
644 ui_.post_connection_alert(conn, action, rule_name);
645 }
646
647 std::ostringstream oss;
648 oss << conn.protocol << ' ' << conn.process_path << ' ' << conn.dst_ip << ':' << conn.dst_port << " -> " << action;
649 if (!rule_name.empty()) oss << " [" << rule_name << ']';
650 log.info(oss.str());
651
652 bsc::netfilter::Decision d;
654 return d;
655}
static Logger & instance()
Definition Logger.cpp:11
std::string reverse_lookup(const std::string &ip) const
std::optional< bsc::model::ProcessInfo > inspect(std::uint32_t pid, bool checksums=false) const
Definition ProcMon.cpp:192
std::optional< Rule > find_match(const bsc::model::Connection &conn) const
Definition Rule.cpp:358
void enrich_from_recent_processes(bsc::model::Connection &conn, std::chrono::milliseconds max_age=std::chrono::milliseconds(5000))
void verdict_store(const bsc::model::Connection &c, const bsc::rule::Rule &r)
bsc::net::DnsResolver dns_
void remember_connection(const bsc::model::Connection &conn)
std::optional< CachedVerdict > verdict_lookup(const bsc::model::Connection &c) const
void persist_learned_rule(const bsc::model::Connection &conn, const bsc::rule::Rule &decision)
void enrich_from_recent_flows(bsc::model::Connection &conn)
void record(const bsc::model::Connection &conn, const std::string &action, const std::string &rule_name)
bool post_connection_alert(const bsc::model::Connection &conn, const std::string &action, const std::string &rule_name={})
Definition UIClient.cpp:467
std::optional< bsc::rule::Rule > ask_rule(const bsc::model::Connection &conn)
Definition UIClient.cpp:389
void merge_process_info(bsc::model::Connection &conn, const bsc::model::ProcessInfo &p)
bool has_process_identity(const bsc::model::Connection &c)
std::string default_duration
Definition Config.hpp:53
std::string default_action
Definition Config.hpp:52
std::uint32_t process_id
std::uint32_t dst_port
std::uint32_t user_id

References bsc::netfilter::Accept, config_, decide_connection(), desktop_allows_activity(), dns_, bsc::netfilter::Drop, bsc::model::Connection::dst_host, bsc::model::Connection::dst_ip, bsc::model::Connection::dst_port, enrich_from_recent_flows(), enrich_from_recent_processes(), bsc::logging::Logger::instance(), is_asking_, persist_learned_rule(), proc_, bsc::model::Connection::process_comm, bsc::model::Connection::process_id, bsc::model::Connection::process_path, bsc::model::Connection::protocol, remember_connection(), rules_, stats_, ui_, bsc::model::Connection::user_id, bsc::netfilter::Decision::verdict, verdict_lookup(), and verdict_store().

Referenced by decide_connection(), run(), and scan_connections().

◆ desktop_allows_activity()

bool bsc::service::DaemonService::desktop_allows_activity ( ) const
private

Definition at line 234 of file DaemonService.cpp.

234 {
235 return desktop_active_.load() && ui_.is_connected();
236}
std::atomic_bool desktop_active_
bool is_connected() const noexcept
Definition UIClient.cpp:380

References desktop_active_, desktop_allows_activity(), and ui_.

Referenced by decide_connection(), desktop_allows_activity(), and scan_connections().

◆ enrich_from_recent_flows()

void bsc::service::DaemonService::enrich_from_recent_flows ( bsc::model::Connection & conn)
private

Definition at line 458 of file DaemonService.cpp.

458 {
459 const auto now = std::chrono::steady_clock::now();
460 std::lock_guard lock(flow_mutex_);
461 for (auto it = recent_flows_.begin(); it != recent_flows_.end();) {
462 if (now - it->second.second > kRecentFlowTtl) {
463 it = recent_flows_.erase(it);
464 continue;
465 }
466 const auto& cached = it->second.first;
467 const bool same_direct = conn.protocol == cached.protocol && conn.src_ip == cached.src_ip && conn.src_port == cached.src_port && conn.dst_ip == cached.dst_ip && conn.dst_port == cached.dst_port;
468 const bool same_reverse = conn.protocol == cached.protocol && conn.src_ip == cached.dst_ip && conn.src_port == cached.dst_port && conn.dst_ip == cached.src_ip && conn.dst_port == cached.src_port;
469 if (same_direct || same_reverse) {
470 if (conn.process_id == 0) conn.process_id = cached.process_id;
471 if (conn.user_id == 0xffffffffu) conn.user_id = cached.user_id;
472 if (conn.process_path.empty()) conn.process_path = cached.process_path;
473 if (conn.process_comm.empty() || looks_like_browser_thread_comm(conn.process_comm)) conn.process_comm = cached.process_comm;
474 if (conn.process_cwd.empty()) conn.process_cwd = cached.process_cwd;
475 if (conn.process_args.empty()) conn.process_args = cached.process_args;
476 if (conn.process_env.empty()) conn.process_env = cached.process_env;
477 if (conn.process_checksums.empty()) conn.process_checksums = cached.process_checksums;
478 if (conn.process_tree.empty()) conn.process_tree = cached.process_tree;
479 return;
480 }
481 ++it;
482 }
483}
std::unordered_map< std::string, std::pair< bsc::model::Connection, std::chrono::steady_clock::time_point > > recent_flows_
bool looks_like_browser_thread_comm(const std::string &comm)
std::vector< std::pair< std::string, std::uint32_t > > process_tree
std::vector< std::string > process_args
std::uint32_t src_port
std::map< std::string, std::string > process_checksums
std::map< std::string, std::string > process_env

References bsc::model::Connection::dst_ip, bsc::model::Connection::dst_port, enrich_from_recent_flows(), flow_mutex_, bsc::model::Connection::process_args, bsc::model::Connection::process_checksums, bsc::model::Connection::process_comm, bsc::model::Connection::process_cwd, bsc::model::Connection::process_env, bsc::model::Connection::process_id, bsc::model::Connection::process_path, bsc::model::Connection::process_tree, bsc::model::Connection::protocol, recent_flows_, bsc::model::Connection::src_ip, bsc::model::Connection::src_port, and bsc::model::Connection::user_id.

Referenced by decide_connection(), enrich_from_recent_flows(), and run().

◆ enrich_from_recent_processes()

void bsc::service::DaemonService::enrich_from_recent_processes ( bsc::model::Connection & conn,
std::chrono::milliseconds max_age = std::chrono::milliseconds(5000) )
private

Definition at line 485 of file DaemonService.cpp.

485 {
486 if (conn.process_id != 0 && !conn.process_comm.empty() && !conn.process_path.empty()) return;
487
488 std::vector<bsc::model::ProcessInfo> candidates;
489 if (conn.user_id != 0xffffffffu) candidates = proc_.recent_candidates(conn.user_id, max_age, 8);
490 else candidates = proc_.recent_candidates_any(max_age, 4);
491 if (candidates.empty()) return;
492
493 const auto& best = candidates.front();
494 bool unambiguous = candidates.size() == 1;
495 if (!unambiguous) {
496 unambiguous = true;
497 for (std::size_t i = 1; i < std::min<std::size_t>(candidates.size(), 3); ++i) {
498 if (!same_process_signature(best, candidates[i])) {
499 unambiguous = false;
500 break;
501 }
502 }
503 }
504 if (!unambiguous) return;
505 merge_process_info(conn, best);
506}
std::vector< bsc::model::ProcessInfo > recent_candidates_any(std::chrono::milliseconds max_age=std::chrono::milliseconds(1500), std::size_t limit=8) const
Definition ProcMon.cpp:165
std::vector< bsc::model::ProcessInfo > recent_candidates(std::uint32_t uid, std::chrono::milliseconds max_age=std::chrono::milliseconds(5000), std::size_t limit=8) const
Definition ProcMon.cpp:135
bool same_process_signature(const bsc::model::ProcessInfo &a, const bsc::model::ProcessInfo &b)

References enrich_from_recent_processes(), proc_, bsc::model::Connection::process_comm, bsc::model::Connection::process_id, bsc::model::Connection::process_path, and bsc::model::Connection::user_id.

Referenced by decide_connection(), enrich_from_recent_processes(), and run().

◆ handle_notification()

void bsc::service::DaemonService::handle_notification ( const bsc::ui::NotificationEvent & ev)
private

Definition at line 298 of file DaemonService.cpp.

298 {
299 auto& log = bsc::logging::Logger::instance();
300 log.info("notification: " + ev.type);
301
302 // I tipi sono lowercase (mapping stringhe definito in ipc/UIServer.cpp).
303 if (ev.type == "reload_fw_rules") {
305 } else if (ev.type == "stop") {
306 stop();
307 } else if (ev.type == "enable_interception") {
309 } else if (ev.type == "disable_interception") {
311 } else if (ev.type == "desktop_active") {
312 set_desktop_active(true);
313 } else if (ev.type == "desktop_idle") {
314 set_desktop_active(false);
315 } else if (ev.type == "enable_firewall") {
317 tasks_.every("firewall_reload",
318 parse_interval(config_.fw_options.monitor_interval, std::chrono::seconds(15)),
319 [this]() { reload_firewall(); });
320 } else if (ev.type == "disable_firewall") {
321 log.warning("disable firewall: sospendo i reload periodici");
322 tasks_.stop_task("firewall_reload");
323 } else if (ev.type == "task_stop") {
324 try {
325 auto j = json::parse(ev.data);
326 const auto name = j.value("Name", std::string{});
327 if (!name.empty()) tasks_.stop_task(name);
328 } catch (...) { log.warning("task_stop con JSON non valido"); }
329 } else if (ev.type == "task_start") {
330 try {
331 auto j = json::parse(ev.data);
332 const auto name = j.value("Name", std::string{});
333 const auto interval = parse_interval(j.value("Interval", std::string{"5s"}), std::chrono::seconds(5));
334 if (name == "scan") tasks_.every("scan", interval, [this]() { scan_connections(); });
335 else if (name == "heartbeat") tasks_.every("heartbeat", interval, [this]() { heartbeat(); });
336 else if (name == "rules_reload") tasks_.every("rules_reload", interval, [this]() { reload_rules(); });
337 else if (name == "firewall_reload") tasks_.every("firewall_reload", interval, [this]() { reload_firewall(); });
338 } catch (...) { log.warning("task_start con JSON non valido"); }
339 } else if (ev.type == "log_level") {
340 try {
341 auto lvl = std::stoi(ev.data);
342 config_.log_level = lvl <= 0 ? 0 : lvl >= 3 ? 3 : lvl;
344 } catch (...) { log.warning("log_level non valido"); }
345 } else if (ev.type == "change_rule" || ev.type == "enable_rule" || ev.type == "disable_rule") {
346 for (auto r : ev.rules) {
347 if (ev.type == "disable_rule") r.enabled = false;
348 if (ev.type == "enable_rule") r.enabled = true;
350 }
351 reload_rules();
352 } else if (ev.type == "delete_rule") {
353 for (const auto& r : ev.rules) {
354 std::error_code ec;
355 fs::remove(fs::path(config_.rules.path) / (r.name + ".json"), ec);
356 }
357 reload_rules();
358 } else if (ev.type == "change_config") {
359 try {
360 auto j = json::parse(ev.data);
361 if (j.contains("DefaultAction")) config_.default_action = j["DefaultAction"].get<std::string>();
362 if (j.contains("DefaultDuration")) config_.default_duration = j["DefaultDuration"].get<std::string>();
363 if (j.contains("Firewall")) config_.firewall = j["Firewall"].get<std::string>();
364 if (j.contains("ProcMonitorMethod")) config_.proc_monitor_method = j["ProcMonitorMethod"].get<std::string>();
365 if (j.contains("EBPFObjPath")) config_.ebpf_obj_path = j["EBPFObjPath"].get<std::string>();
366 if (j.contains("InterceptUnknown")) config_.intercept_unknown = j["InterceptUnknown"].get<bool>();
367 if (j.contains("LogUTC")) config_.log_utc = j["LogUTC"].get<bool>();
368 if (j.contains("LogMicro")) config_.log_micro = j["LogMicro"].get<bool>();
369 if (j.contains("LogLevel")) {
370 config_.log_level = j["LogLevel"].get<int>();
372 config_.log_level <= 0 ? 0 : config_.log_level >= 3 ? 3 : config_.log_level));
373 }
376 const auto target = config_.source_path.empty()
377 ? std::string{"/etc/bastionguard-secure-connectiond/default-config.json"}
379 (void)bsc::config::save_file(config_, target);
380 } catch (...) { log.warning("change_config con JSON non valido"); }
381 }
382}
bool reload(const std::string &config_path) const
Definition Firewall.cpp:394
void set_microseconds(bool enabled)
Definition Logger.cpp:18
void set_utc(bool enabled)
Definition Logger.cpp:17
void set_level(Level level)
Definition Logger.cpp:16
bool save_rule(const Rule &rule, const std::string &dir) const
Definition Rule.cpp:342
static std::chrono::milliseconds parse_interval(const std::string &v, std::chrono::milliseconds def=std::chrono::seconds(5))
void set_desktop_active(bool active)
bsc::task::TaskRunner tasks_
bool stop_task(const std::string &name)
void every(const std::string &name, std::chrono::milliseconds interval, std::function< void()> fn)
Definition TaskRunner.cpp:9
bool save_file(const Config &cfg, const std::string &path)
Definition Config.cpp:104
std::string proc_monitor_method
Definition Config.hpp:54
std::int32_t log_level
Definition Config.hpp:50
std::string ebpf_obj_path
Definition Config.hpp:55
FwOptions fw_options
Definition Config.hpp:56
std::string source_path
Definition Config.hpp:49
std::vector< bsc::rule::Rule > rules
Definition UIClient.hpp:25

References config_, bsc::ui::NotificationEvent::data, firewall_, handle_notification(), heartbeat(), bsc::logging::Logger::instance(), parse_interval(), reload_firewall(), reload_rules(), bsc::ui::NotificationEvent::rules, rules_, bsc::config::save_file(), scan_connections(), set_desktop_active(), bsc::logging::Logger::set_level(), bsc::logging::Logger::set_microseconds(), bsc::logging::Logger::set_utc(), stop(), tasks_, and bsc::ui::NotificationEvent::type.

Referenced by handle_notification(), and run().

◆ handle_proc_event()

void bsc::service::DaemonService::handle_proc_event ( const bsc::netlink::ProcEvent & ev)
private

Definition at line 384 of file DaemonService.cpp.

384 {
385 auto& log = bsc::logging::Logger::instance();
386 const auto pid = ev.tgid ? ev.tgid : ev.pid;
389 log.debug("fork pid=" + std::to_string(pid) + " ppid=" + std::to_string(ev.parent_tgid ? ev.parent_tgid : ev.parent_pid));
390 } else if (ev.type == bsc::netlink::ProcEvent::Type::Exec) {
392 if (auto p = proc_.cached(pid, false)) {
393 log.debug("exec pid=" + std::to_string(p->pid) + " path=" + p->path);
394 }
395 } else if (ev.type == bsc::netlink::ProcEvent::Type::Exit) {
396 proc_.note_exit(pid);
397 log.debug("exit pid=" + std::to_string(pid) + " code=" + std::to_string(ev.exit_code));
398 }
399}
void note_exit(std::uint32_t pid) const
Definition ProcMon.cpp:263
std::optional< bsc::model::ProcessInfo > cached(std::uint32_t pid, bool allow_recent_exit=true) const
Definition ProcMon.cpp:122
void note_fork(std::uint32_t child_pid, std::uint32_t parent_pid) const
Definition ProcMon.cpp:242
void note_exec(std::uint32_t pid, bool checksums=false) const
Definition ProcMon.cpp:257

References config_, bsc::netlink::ProcEvent::Exec, bsc::netlink::ProcEvent::Exit, bsc::netlink::ProcEvent::exit_code, bsc::netlink::ProcEvent::Fork, handle_proc_event(), bsc::logging::Logger::instance(), bsc::netlink::ProcEvent::parent_pid, bsc::netlink::ProcEvent::parent_tgid, bsc::netlink::ProcEvent::pid, proc_, bsc::netlink::ProcEvent::tgid, and bsc::netlink::ProcEvent::type.

Referenced by handle_proc_event().

◆ heartbeat()

void bsc::service::DaemonService::heartbeat ( )
private

Definition at line 681 of file DaemonService.cpp.

681 {
682 ui_.ping(stats_);
683}
bool ping(const bsc::stats::Statistics &stats)
Definition UIClient.cpp:436

References heartbeat(), stats_, and ui_.

Referenced by handle_notification(), heartbeat(), and run().

◆ parse_interval()

std::chrono::milliseconds bsc::service::DaemonService::parse_interval ( const std::string & v,
std::chrono::milliseconds def = std::chrono::seconds(5) )
staticprivate

Definition at line 67 of file DaemonService.cpp.

67 {
68 if (v.empty()) return def;
69 try {
70 if (v.ends_with("ms")) return std::chrono::milliseconds(std::stoll(v.substr(0, v.size() - 2)));
71 if (v.ends_with("s")) return std::chrono::seconds(std::stoll(v.substr(0, v.size() - 1)));
72 if (v.ends_with("m")) return std::chrono::minutes(std::stoll(v.substr(0, v.size() - 1)));
73 } catch (...) {}
74 return def;
75}

Referenced by handle_notification(), and run().

◆ persist_learned_rule()

void bsc::service::DaemonService::persist_learned_rule ( const bsc::model::Connection & conn,
const bsc::rule::Rule & decision )
private

Definition at line 401 of file DaemonService.cpp.

401 {
402 if (decision.duration != "always") return;
403 bsc::rule::Rule persisted = decision;
404 persisted.created = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
405 if (persisted.name.empty()) {
406 std::ostringstream name;
407 name << "autogen-" << persisted.action << '-' << conn.process_id << '-' << conn.dst_port << '-' << std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
408 persisted.name = name.str();
409 }
410 persisted.description = "Auto-generated from UI decision";
411 persisted.enabled = true;
412 persisted.precedence = false;
413 persisted.nolog = false;
414
415 bsc::rule::Operator proc_op;
417 if (!conn.process_path.empty()) {
418 proc_op.operand = "process.path";
419 proc_op.data = conn.process_path;
420 } else if (!conn.process_comm.empty()) {
421 proc_op.operand = "process.name";
422 proc_op.data = conn.process_comm;
423 } else {
424 proc_op.operand = "process.id";
425 proc_op.data = std::to_string(conn.process_id);
426 }
427 bsc::rule::Operator host_op;
429 host_op.operand = !conn.dst_host.empty() ? "dest.host" : "dest.ip";
430 host_op.data = !conn.dst_host.empty() ? conn.dst_host : conn.dst_ip;
431 bsc::rule::Operator port_op;
433 port_op.operand = "dest.port";
434 port_op.data = std::to_string(conn.dst_port);
436 persisted.op.operand = "list";
437 persisted.op.list = {proc_op, host_op, port_op};
438
439 if (rules_.save_rule(persisted, config_.rules.path)) {
440 reload_rules();
441 ui_.post_alert("Regola persistente salvata: " + persisted.name);
442 }
443}
bool post_alert(const std::string &text)
Definition UIClient.cpp:456
std::string operand
Definition Rule.hpp:15
std::string data
Definition Rule.hpp:16
OperatorType type
Definition Rule.hpp:14
std::vector< Operator > list
Definition Rule.hpp:18
bool precedence
Definition Rule.hpp:28
std::string name
Definition Rule.hpp:25
std::string duration
Definition Rule.hpp:31
Operator op
Definition Rule.hpp:32
std::string action
Definition Rule.hpp:30
std::string description
Definition Rule.hpp:26
std::int64_t created
Definition Rule.hpp:24

References bsc::rule::Rule::action, config_, bsc::rule::Rule::created, bsc::rule::Operator::data, bsc::rule::Rule::description, bsc::model::Connection::dst_host, bsc::model::Connection::dst_ip, bsc::model::Connection::dst_port, bsc::rule::Rule::duration, bsc::rule::Rule::enabled, bsc::rule::List, bsc::rule::Operator::list, bsc::rule::Rule::name, bsc::rule::Rule::nolog, bsc::rule::Rule::op, bsc::rule::Operator::operand, persist_learned_rule(), bsc::rule::Rule::precedence, bsc::model::Connection::process_comm, bsc::model::Connection::process_id, bsc::model::Connection::process_path, reload_rules(), rules_, bsc::rule::Simple, bsc::rule::Operator::type, and ui_.

Referenced by decide_connection(), and persist_learned_rule().

◆ reload_firewall()

void bsc::service::DaemonService::reload_firewall ( )
private

Definition at line 283 of file DaemonService.cpp.

283 {
284 if (config_.fw_options.config_path.empty()) {
285 return;
286 }
287
289 const std::string message =
290 std::string{_("Reload firewall fallito: ")} +
292
294 ui_.post_alert(message);
295 }
296}
#define _(s)
void warning(const std::string &msg)
Definition Logger.cpp:22

References _, config_, firewall_, bsc::logging::Logger::instance(), reload_firewall(), ui_, and bsc::logging::Logger::warning().

Referenced by handle_notification(), reload_firewall(), and run().

◆ reload_rules()

void bsc::service::DaemonService::reload_rules ( )
private

Definition at line 274 of file DaemonService.cpp.

274 {
275 std::lock_guard lock(rules_reload_mutex_);
276 if (rules_changed()) {
277 const auto aliases = std::filesystem::path(config_.rules.path).parent_path() / "network_aliases.json";
278 rules_.load_aliases(aliases.string());
280 }
281}

References config_, reload_rules(), rules_, rules_changed(), and rules_reload_mutex_.

Referenced by handle_notification(), persist_learned_rule(), reload_rules(), and run().

◆ remember_connection()

void bsc::service::DaemonService::remember_connection ( const bsc::model::Connection & conn)
private

Definition at line 445 of file DaemonService.cpp.

445 {
446 if (conn.process_id == 0 && conn.process_path.empty() && conn.user_id == 0xffffffffu) return;
447 const auto now = std::chrono::steady_clock::now();
448 std::lock_guard lock(flow_mutex_);
449 recent_flows_[conn.key()] = {conn, now};
450 if (recent_flows_.size() > 4096) {
451 for (auto it = recent_flows_.begin(); it != recent_flows_.end();) {
452 if (now - it->second.second > kRecentFlowTtl) it = recent_flows_.erase(it);
453 else ++it;
454 }
455 }
456}
std::string key() const
Definition Connection.cpp:6

References flow_mutex_, bsc::model::Connection::key(), bsc::model::Connection::process_id, bsc::model::Connection::process_path, recent_flows_, remember_connection(), and bsc::model::Connection::user_id.

Referenced by decide_connection(), and remember_connection().

◆ rules_changed()

bool bsc::service::DaemonService::rules_changed ( ) const
private

Definition at line 261 of file DaemonService.cpp.

261 {
262 std::error_code ec;
263 fs::file_time_type latest{};
264 if (!fs::exists(config_.rules.path, ec)) return false;
265 for (const auto& entry : fs::directory_iterator(config_.rules.path, ec)) {
266 if (!entry.is_regular_file() || entry.path().extension() != ".json") continue;
267 latest = std::max(latest, fs::last_write_time(entry.path(), ec));
268 }
269 const bool changed = latest != rules_mtime_;
270 if (changed) const_cast<DaemonService*>(this)->rules_mtime_ = latest;
271 return changed;
272}
DaemonService(bsc::config::Config config)
std::filesystem::file_time_type rules_mtime_

References config_, DaemonService(), rules_changed(), and rules_mtime_.

Referenced by DaemonService(), reload_rules(), and rules_changed().

◆ run()

void bsc::service::DaemonService::run ( )

Definition at line 85 of file DaemonService.cpp.

85 {
87
88 // Registra l'handler per le notifiche in arrivo dalla UI (cambio config,
89 // stop, reload regole...). Viene chiamato dal thread reader del
90 // UIClient — deve restare breve.
91 ui_.set_notification_handler([this](const bsc::ui::NotificationEvent& ev) {
93 });
94
95 // Avvia il thread di connessione/riconnessione in background. Non-blocca:
96 // se la UI non e' ancora su (es. daemon partito dal gestore servizi,
97 // utente non ancora loggato), il reconnector interno ritentera' ogni 1s
98 // finche' la UI non compare.
99 ui_.start();
100 log.info("UIClient avviato verso " + config_.server.address);
101
103
104 auto scan_interval = std::chrono::seconds(2);
105 auto heartbeat_interval = std::chrono::seconds(10);
106 auto rules_interval = std::chrono::seconds(3);
107 auto firewall_interval = parse_interval(config_.fw_options.monitor_interval, std::chrono::seconds(15));
108
109 const fs::path tasks_file = fs::path(config_.tasks.config_path) / "tasks.json";
110 if (fs::exists(tasks_file)) {
111 try {
112 std::ifstream in(tasks_file);
113 json j;
114 in >> j;
115 if (j.contains("tasks") && j["tasks"].is_array()) {
116 for (const auto& task : j["tasks"]) {
117 const auto name = task.value("name", std::string{});
118 const auto interval = parse_interval(task.value("interval", std::string{"5s"}), std::chrono::seconds(5));
119 if (name == "scan") {
120 scan_interval = std::chrono::duration_cast<std::chrono::seconds>(interval);
121 } else if (name == "heartbeat") {
122 heartbeat_interval = std::chrono::duration_cast<std::chrono::seconds>(interval);
123 } else if (name == "rules_reload") {
124 rules_interval = std::chrono::duration_cast<std::chrono::seconds>(interval);
125 }
126 else if (name == "firewall_reload") firewall_interval = interval;
127 }
128 }
129 } catch (...) {
130 log.warning("tasks.json non valido, uso gli intervalli di default");
131 }
132 }
133
134 tasks_.every("scan", scan_interval, [this]() { scan_connections(); });
135 tasks_.every("heartbeat", heartbeat_interval, [this]() { heartbeat(); });
136 tasks_.every("rules_reload", rules_interval, [this]() { reload_rules(); });
137 tasks_.every("firewall_reload", firewall_interval, [this]() { reload_firewall(); });
138
139 const auto proc_method = [&]() {
140 auto method = config_.proc_monitor_method;
141 for (auto& ch : method) ch = static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
142 return method;
143 }();
144
145 if (proc_method == "netlink" || proc_method == "proc" || proc_method == "audit" || proc_method == "ebpf") {
146 if (proc_events_.start([this](const bsc::netlink::ProcEvent& ev) { handle_proc_event(ev); })) {
147 log.info("proc event monitor attivo via netlink connector");
148 if (proc_method == "audit" || proc_method == "ebpf") {
149 // Quando l'utente sceglie "ebpf" attiviamo il monitor eBPF
150 // in aggiunta al fallback netlink/proc già avviato sopra.
151 // net_ è il SocketSnapshot condiviso: start_ebpf() carica
152 // il programma BPF e avvia il thread di draining.
153 // Se fallisce (kernel senza BTF, cap assenti) il daemon
154 // prosegue normalmente via NFQUEUE + /proc/net/tcp.
155 if (proc_method == "ebpf") {
156 const auto ebpf_obj = config_.ebpf_obj_path.empty()
157 ? std::string{"/usr/lib/bastionguard-sc/bsc_ebpf.o"}
159 if (net_.start_ebpf(ebpf_obj)) {
160 log.info("eBPF monitor attivo: tracepoint inet_sock_set_state");
161 ui_.post_alert("eBPF monitor attivo — intercettazione a livello kernel");
162 } else {
163 ui_.post_alert("eBPF non disponibile — fallback NFQUEUE+/proc");
164 }
165 } else {
166 ui_.post_alert("ProcMonitorMethod=" + config_.proc_monitor_method + " richiesto: uso netlink/proc come fallback runtime nel port C++");
167 }
168 }
169 } else {
170 log.warning("proc event monitor non disponibile, resto in modalità on-demand /proc");
171 }
172 }
173
175 // Installa la regola nft che dirotta il traffico in NFQUEUE.
176 // Se fallisce (niente nft, niente CAP_NET_ADMIN, kernel senza
177 // nf_tables) restiamo in modalita' polling /proc: gli alert partono
178 // comunque dallo scanner periodico.
179 const bool nft_ok = firewall_.install_nfqueue_rule(
181
182 if (nft_ok && nfqueue_.open(config_.fw_options.queue_num, [this](const bsc::netfilter::PacketInfo& pkt) {
183 if (!desktop_allows_activity()) {
184 bsc::netfilter::Decision d;
185 d.verdict = bsc::netfilter::Verdict::Accept;
186 return d;
187 }
188
189 auto conn = pkt.connection;
190 if (conn.user_id == 0xffffffffu && pkt.uid != 0xffffffffu) conn.user_id = pkt.uid;
191
194
195 for (int i = 0; i < 4 && !has_process_identity(conn); ++i) {
197 std::this_thread::sleep_for(std::chrono::milliseconds(15 + 10 * i));
200 }
201 if (!has_process_identity(conn)) enrich_from_recent_processes(conn, std::chrono::milliseconds(2500));
202 if (!has_process_identity(conn)) enrich_from_recent_processes(conn, std::chrono::milliseconds(6000));
203
204 return decide_connection(std::move(conn), true, false);
205 })) {
206 log.info("NFQUEUE attiva sulla coda " + std::to_string(config_.fw_options.queue_num));
207 ui_.post_alert("NFQUEUE attiva: intercettazione pacchetti in tempo reale");
208 } else {
209 if (nft_ok) firewall_.remove_nfqueue_rule(); // apertura coda fallita, rollback
210 log.warning("NFQUEUE non disponibile: uso polling /proc come fallback");
211 ui_.post_alert("NFQUEUE non disponibile: fallback su /proc snapshot");
212 }
213 }
214
215 log.info("bsc-daemon-cpp started");
216 ui_.post_alert("bsc-daemon-cpp avviato");
217 ui_.post_alert("runtime: proc_monitor_method=" + config_.proc_monitor_method + ", queue_num=" + std::to_string(config_.fw_options.queue_num));
218 while (running_) std::this_thread::sleep_for(std::chrono::milliseconds(250));
219 ui_.post_alert("bsc-daemon-cpp arrestato");
220 // Breve attesa perche' il post_alert pending possa lasciare il processo
221 // attraverso il socket.
222 std::this_thread::sleep_for(std::chrono::milliseconds(200));
223 nfqueue_.close();
224 firewall_.remove_nfqueue_rule(); // pulizia nft all'uscita
226 net_.stop_ebpf(); // detach tracepoint eBPF (no-op se non avviato)
227 tasks_.stop();
228 ui_.stop(); // chiude thread reader + socket
229 log.info("bsc-daemon-cpp stopped");
230}
bool install_nfqueue_rule(std::uint16_t queue_num, bool queue_bypass=true) const
Definition Firewall.cpp:472
void remove_nfqueue_rule() const
Definition Firewall.cpp:583
bool enrich_connection(bsc::model::Connection &conn) const
bool start_ebpf(const std::string &obj_path="/usr/lib/bastionguard-sc/bsc_ebpf.o")
bool open(std::uint16_t queue_id, Handler handler)
Definition NFQueue.cpp:249
bsc::netlink::ProcEventMonitor proc_events_
bsc::netfilter::Decision decide_connection(bsc::model::Connection conn, bool realtime, bool allow_blocking_ask=true)
bsc::net::SocketSnapshot net_
void handle_notification(const bsc::ui::NotificationEvent &ev)
bsc::netfilter::NFQueue nfqueue_
void set_notification_handler(std::function< void(const NotificationEvent &)> cb)
Definition UIClient.cpp:384
bool available()
Definition NFQueue.cpp:251
nlohmann::json json
TasksOptions tasks
Definition Config.hpp:61
bsc::model::Connection connection
Definition NFQueue.hpp:26

References bsc::config::Config::ServerConfig::address, bsc::netfilter::available(), config_, bsc::config::Config::FwOptions::config_path, bsc::config::Config::TasksOptions::config_path, bsc::netfilter::PacketInfo::connection, decide_connection(), bsc::config::Config::ebpf_obj_path, bsc::net::SocketSnapshot::enrich_connection(), enrich_from_recent_flows(), enrich_from_recent_processes(), bsc::task::TaskRunner::every(), firewall_, bsc::config::Config::fw_options, handle_notification(), heartbeat(), bsc::fw::Firewall::install_nfqueue_rule(), bsc::logging::Logger::instance(), bsc::net::SocketSnapshot::invalidate_cache(), bsc::config::Config::FwOptions::monitor_interval, net_, nfqueue_, bsc::netfilter::NFQueue::open(), parse_interval(), bsc::ui::UIClient::post_alert(), proc_events_, bsc::config::Config::proc_monitor_method, bsc::config::Config::FwOptions::queue_bypass, bsc::config::Config::FwOptions::queue_num, bsc::fw::Firewall::reload(), reload_firewall(), reload_rules(), bsc::fw::Firewall::remove_nfqueue_rule(), scan_connections(), bsc::config::Config::server, bsc::ui::UIClient::set_notification_handler(), bsc::netlink::ProcEventMonitor::start(), bsc::ui::UIClient::start(), bsc::net::SocketSnapshot::start_ebpf(), bsc::config::Config::tasks, tasks_, ui_, bsc::netfilter::PacketInfo::uid, and bsc::model::Connection::user_id.

◆ scan_connections()

void bsc::service::DaemonService::scan_connections ( )
private

Definition at line 657 of file DaemonService.cpp.

657 {
659 if (!inactive_notice_logged_.exchange(true)) {
661 "scan sospesa: desktop inattivo o UI non connessa");
662 }
664 return;
665 }
667
668 for (auto conn : net_.list_connections()) {
669 if ((conn.dst_ip == "0.0.0.0" || conn.dst_ip == "::") && conn.dst_port == 0) continue;
670 const auto key = conn.key();
671 {
672 std::lock_guard lock(seen_mutex_);
673 if (seen_.contains(key)) continue;
674 seen_.insert(key);
675 if (seen_.size() > 50000) seen_.clear();
676 }
677 (void)decide_connection(std::move(conn), config_.intercept_unknown, true);
678 }
679}
void info(const std::string &msg)
Definition Logger.cpp:21
std::vector< bsc::model::Connection > list_connections() const
std::set< std::string > seen_
std::atomic_bool inactive_notice_logged_

References config_, decide_connection(), desktop_allows_activity(), inactive_notice_logged_, bsc::logging::Logger::info(), bsc::logging::Logger::instance(), net_, scan_connections(), seen_, and seen_mutex_.

Referenced by handle_notification(), run(), and scan_connections().

◆ set_desktop_active()

void bsc::service::DaemonService::set_desktop_active ( bool active)
private

Definition at line 238 of file DaemonService.cpp.

238 {
239 const bool previous = desktop_active_.exchange(active);
240 if (previous == active) return;
241
242 auto& log = bsc::logging::Logger::instance();
243 if (active) {
245 {
246 std::lock_guard lock(seen_mutex_);
247 seen_.clear();
248 }
250 log.info("Desktop attivo: monitoraggio connessioni riattivato");
251 } else {
252 {
253 std::lock_guard lock(seen_mutex_);
254 seen_.clear();
255 }
257 log.info("Desktop inattivo/bloccato: sospendo scansione e popup connessioni");
258 }
259}

References desktop_active_, inactive_notice_logged_, bsc::logging::Logger::instance(), net_, seen_, seen_mutex_, and set_desktop_active().

Referenced by handle_notification(), and set_desktop_active().

◆ stop()

void bsc::service::DaemonService::stop ( )

Definition at line 232 of file DaemonService.cpp.

232{ running_ = false; }

References running_, and stop().

Referenced by handle_notification(), and stop().

◆ verdict_key()

std::string bsc::service::DaemonService::verdict_key ( const bsc::model::Connection & c)
staticprivate

Definition at line 508 of file DaemonService.cpp.

508 {
509 const std::string host = !c.dst_host.empty() ? c.dst_host : c.dst_ip;
510 std::string proc_key = !c.process_path.empty() ? c.process_path : c.process_comm;
511 if (proc_key.empty() && c.process_id != 0) proc_key = "pid:" + std::to_string(c.process_id);
512 return proc_key + "|" + host + "|" + std::to_string(c.dst_port);
513}

References bsc::model::Connection::dst_host, bsc::model::Connection::dst_ip, bsc::model::Connection::dst_port, bsc::model::Connection::process_comm, bsc::model::Connection::process_id, bsc::model::Connection::process_path, and verdict_key().

Referenced by verdict_key(), verdict_lookup(), and verdict_store().

◆ verdict_lookup()

std::optional< DaemonService::CachedVerdict > bsc::service::DaemonService::verdict_lookup ( const bsc::model::Connection & c) const
private

Definition at line 516 of file DaemonService.cpp.

516 {
517 const auto key = verdict_key(c);
518 const auto now = std::chrono::steady_clock::now();
519 std::lock_guard lk(verdict_cache_mutex_);
520 auto it = verdict_cache_.find(key);
521 if (it == verdict_cache_.end()) return std::nullopt;
522 if (it->second.expires_at != std::chrono::steady_clock::time_point{} &&
523 now >= it->second.expires_at) {
524 return std::nullopt; // scaduto
525 }
526 return it->second;
527}
static std::string verdict_key(const bsc::model::Connection &c)
std::unordered_map< std::string, CachedVerdict > verdict_cache_

References verdict_cache_, verdict_cache_mutex_, verdict_key(), and verdict_lookup().

Referenced by decide_connection(), and verdict_lookup().

◆ verdict_store()

void bsc::service::DaemonService::verdict_store ( const bsc::model::Connection & c,
const bsc::rule::Rule & r )
private

Definition at line 529 of file DaemonService.cpp.

529 {
530 // Memorizziamo SOLO verdetti "always": once e' per definizione one-shot.
531 // Per "always" teniamo scadenza infinita (salvato anche su disco come
532 // regola — vedi persist_learned_rule).
533 if (r.duration != "always") return;
534 CachedVerdict cv{r.action, r.duration, std::chrono::steady_clock::time_point{}};
535 std::lock_guard lk(verdict_cache_mutex_);
536 verdict_cache_[verdict_key(c)] = std::move(cv);
537 // Bound di sicurezza: dimentica il piu' vecchio se superiamo 4096 entry.
538 if (verdict_cache_.size() > 4096) {
539 auto oldest = verdict_cache_.begin();
540 verdict_cache_.erase(oldest);
541 }
542}

References verdict_cache_, verdict_cache_mutex_, verdict_key(), and verdict_store().

Referenced by decide_connection(), and verdict_store().

Member Data Documentation

◆ config_

◆ desktop_active_

std::atomic_bool bsc::service::DaemonService::desktop_active_ {false}
private

Definition at line 92 of file DaemonService.hpp.

Referenced by desktop_allows_activity(), and set_desktop_active().

◆ dns_

bsc::net::DnsResolver bsc::service::DaemonService::dns_
private

Definition at line 50 of file DaemonService.hpp.

Referenced by decide_connection().

◆ firewall_

bsc::fw::Firewall bsc::service::DaemonService::firewall_
private

Definition at line 49 of file DaemonService.hpp.

Referenced by DaemonService(), handle_notification(), reload_firewall(), and run().

◆ flow_mutex_

std::mutex bsc::service::DaemonService::flow_mutex_
mutableprivate

Definition at line 63 of file DaemonService.hpp.

Referenced by enrich_from_recent_flows(), and remember_connection().

◆ inactive_notice_logged_

std::atomic_bool bsc::service::DaemonService::inactive_notice_logged_ {false}
private

Definition at line 93 of file DaemonService.hpp.

Referenced by scan_connections(), and set_desktop_active().

◆ is_asking_

std::atomic_bool bsc::service::DaemonService::is_asking_ {false}
private

Definition at line 87 of file DaemonService.hpp.

Referenced by decide_connection().

◆ net_

bsc::net::SocketSnapshot bsc::service::DaemonService::net_
private

Definition at line 52 of file DaemonService.hpp.

Referenced by run(), scan_connections(), and set_desktop_active().

◆ nfqueue_

bsc::netfilter::NFQueue bsc::service::DaemonService::nfqueue_
private

Definition at line 53 of file DaemonService.hpp.

Referenced by run().

◆ proc_

bsc::proc::ProcMon bsc::service::DaemonService::proc_
private

◆ proc_events_

bsc::netlink::ProcEventMonitor bsc::service::DaemonService::proc_events_
private

Definition at line 51 of file DaemonService.hpp.

Referenced by run().

◆ recent_flows_

std::unordered_map<std::string, std::pair<bsc::model::Connection, std::chrono::steady_clock::time_point> > bsc::service::DaemonService::recent_flows_
private

Definition at line 64 of file DaemonService.hpp.

Referenced by enrich_from_recent_flows(), and remember_connection().

◆ rules_

bsc::rule::Loader bsc::service::DaemonService::rules_
private

◆ rules_mtime_

std::filesystem::file_time_type bsc::service::DaemonService::rules_mtime_ {}
private

Definition at line 95 of file DaemonService.hpp.

Referenced by rules_changed().

◆ rules_reload_mutex_

std::mutex bsc::service::DaemonService::rules_reload_mutex_
mutableprivate

Definition at line 62 of file DaemonService.hpp.

Referenced by reload_rules().

◆ running_

std::atomic_bool bsc::service::DaemonService::running_ {true}
private

Definition at line 59 of file DaemonService.hpp.

Referenced by stop().

◆ seen_

std::set<std::string> bsc::service::DaemonService::seen_
private

Definition at line 61 of file DaemonService.hpp.

Referenced by scan_connections(), and set_desktop_active().

◆ seen_mutex_

std::mutex bsc::service::DaemonService::seen_mutex_
private

Definition at line 60 of file DaemonService.hpp.

Referenced by scan_connections(), and set_desktop_active().

◆ start_time_

std::chrono::steady_clock::time_point bsc::service::DaemonService::start_time_ {std::chrono::steady_clock::now()}
private

Definition at line 96 of file DaemonService.hpp.

◆ stats_

bsc::stats::Statistics bsc::service::DaemonService::stats_
private

Definition at line 56 of file DaemonService.hpp.

Referenced by DaemonService(), decide_connection(), and heartbeat().

◆ tasks_

bsc::task::TaskRunner bsc::service::DaemonService::tasks_
private

Definition at line 58 of file DaemonService.hpp.

Referenced by handle_notification(), and run().

◆ ui_

bsc::ui::UIClient bsc::service::DaemonService::ui_
private

◆ verdict_cache_

std::unordered_map<std::string, CachedVerdict> bsc::service::DaemonService::verdict_cache_
private

Definition at line 77 of file DaemonService.hpp.

Referenced by verdict_lookup(), and verdict_store().

◆ verdict_cache_mutex_

std::mutex bsc::service::DaemonService::verdict_cache_mutex_
mutableprivate

Definition at line 76 of file DaemonService.hpp.

Referenced by verdict_lookup(), and verdict_store().


The documentation for this class was generated from the following files:
  • BastionGuard/thirdparty/bastionguard-secure-connection/daemon/include/bsc/service/DaemonService.hpp
  • BastionGuard/thirdparty/bastionguard-secure-connection/daemon/src/service/DaemonService.cpp