SocketSnapshot.cpp

1. Overview

Connection discovery and enrichment engine. Combines eBPF events, /proc/net socket tables, inode-to-PID mapping and sock_diag lookups. It deduplicates flows, caches snapshots and resolves process identity for intercepted packets.

The original source path is:

src/net/SocketSnapshot.cpp

2. Role in the Daemon

This file participates in the privileged BastionGuard Secure Connection daemon. It uses the shared bsc models and follows the daemon-wide fallback strategy: optional high-fidelity backends are used when available, while portable polling or stub behavior preserves service startup.


3. Namespaces

  • bsc::net
  • fs

4. Dependencies and Included Interfaces

  • bsc/net/SocketSnapshot.hpp
  • bsc/net/SockDiag.hpp
  • arpa/inet.h
  • algorithm
  • cctype
  • chrono
  • cstring
  • dirent.h
  • filesystem
  • fstream
  • set
  • sstream
  • string
  • sys/stat.h
  • thread
  • unistd.h
  • unordered_map
  • unordered_set

5. Declared Types

  • struct Row

6. API and Functions

The file declares or implements the following callable entry points:

  • inode_cache_lookup(const std::string& inode)
  • inode_cache_store(const std::string& inode, std::uint32_t pid)
  • ebpf_flow_cache_store(const bsc::model::Connection& conn)
  • ebpf_flow_cache_store_many(const std::vector<bsc::model::Connection>& conns)
  • trim_trailing_ws(std::string s)
  • read_proc_comm(std::uint32_t pid)
  • hex_ipv4(const std::string& s)
  • hex_ipv6(const std::string& s)
  • hex_port(const std::string& s)
  • parse_file(const std::string& path, const std::string& proto, bool ipv6)
  • SocketSnapshot::start_ebpf(const std::string& obj_path)
  • SocketSnapshot::stop_ebpf()
  • SocketSnapshot::list_connections()
  • SocketSnapshot::invalidate_cache()
  • SocketSnapshot::discard_pending_events()
  • SocketSnapshot::find_connection(const bsc::model::Connection& needle)
  • SocketSnapshot::enrich_connection(bsc::model::Connection& conn)

7. Constants and Compile-Time Controls

  • auto kSnapshotTtl = std::chrono::milliseconds(500)
  • auto kInodeCacheTtl = std::chrono::seconds(90)
  • auto kEbpfFlowCacheTtl = std::chrono::seconds(12)
  • auto now = std::chrono::steady_clock::now()
  • auto it = g_inode_pid_cache.find(inode)
  • int base = word * 8
  • int pos = base + (3 - byte) * 2
  • auto byte_hex = s.substr(pos, 2)
  • auto local_ip = ipv6 ? hex_ipv6(local.substr(0, lp)) : hex_ipv4(local.substr(0, lp))
  • auto rem_ip = ipv6 ? hex_ipv6(rem.substr(0, rp)) : hex_ipv4(rem.substr(0, rp))
  • bool is_udp = normalize_proto(conn.protocol) == "udp"
  • auto inode_str = std::to_string(info->inode)
  • auto pid = find_pid_by_inode_direct(inode_str)
  • auto inode = find_inode_for_flow(conn)
  • auto pid = find_pid_by_inode_direct(inode)

8. Operational Flow

  1. Drain new eBPF events and retain them in a short-lived flow cache.
  2. Parse /proc/net/tcp, tcp6, udp and udp6 as a compatibility and pre-existing-connection source.
  3. Map socket inodes to processes using a cache and /proc/<pid>/fd scans.
  4. For targeted NFQUEUE enrichment, try sock_diag first, then cached snapshots and finally a direct inode/PID search.

9. Connection Sources

  • eBPF ring-buffer events for low-latency process and endpoint identity.
  • /proc/net/tcp, tcp6, udp and udp6 for fallback and pre-existing sockets.
  • NETLINK_SOCK_DIAG for targeted inode/UID lookup.
  • /proc/<pid>/fd symbolic links for inode-to-process mapping.

10. External Resources and Protocol Values

Relevant paths, endpoints, command names or policy values referenced by this file include:

  • bsc/net/SocketSnapshot.hpp
  • bsc/net/SockDiag.hpp
  • /proc/
  • /comm
  • /proc
  • /fd
  • /proc/net/tcp
  • /proc/net/tcp6
  • /proc/net/udp
  • /proc/net/udp6

11. Concurrency and Lifecycle

  • Protects mutable shared data with std::mutex.

12. Security Considerations

  • The component processes privileged operating-system or network data and should run with only the capabilities required by its backend.

13. Implementation Considerations

  • Shared state is protected by mutexes; callers should avoid holding external locks while invoking callbacks.
  • Linux /proc data can disappear between reads because processes and sockets are inherently short-lived.

14. Source Metrics

MetricValue
File size22859 bytes
Lines518
Detected API entries17
Detected types1