How Sniffnet's Favorite System Manages Network Hosts and Services

Sniffnet maintains a persistent, in-memory collection of favorite network entities using three HashSets stored in the Favorites struct, enabling O(1) membership checks, UI star toggles, filtered reporting, and real-time traffic alerts for specific hosts, services, and programs.

The Sniffnet network monitoring application (GyulyVGC/sniffnet) implements a comprehensive favorite system that persists user preferences across sessions via serialized configuration. This system tracks three distinct entity types—network hosts, services, and application programs—allowing security analysts and network administrators to focus monitoring on critical infrastructure components.

Core Data Structures

The favorite system centers on src/gui/types/favorite.rs, which defines the storage containers and access patterns that enable efficient favorite management.

The Favorites Struct

At the heart of the system lies the Favorites struct, which encapsulates three separate HashSet instances. Each set stores a different entity type and derives serialization traits for persistent storage in the user's configuration file.

#[derive(Clone, Default, PartialEq, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct Favorites {
    #[serde(deserialize_with = "deserialize_or_default")]
    hosts: HashSet<Host>,
    #[serde(deserialize_with = "deserialize_or_default")]
    services: HashSet<Service>,
    #[serde(deserialize_with = "deserialize_or_default")]
    programs: HashSet<Program>,
}

This structure ensures that favorites survive application restarts while providing constant-time complexity for membership tests.

The FavoriteKey Enum

To abstract over the three entity types, Sniffnet uses the FavoriteKey enum that unifies hosts, services, and programs under a single interface. This pattern enables generic insertion and removal operations without exposing internal storage details.

pub enum FavoriteKey {
    Host(Host),
    Service(Service),
    Program(Program),
}

The Favorites::insert and Favorites::remove methods pattern-match on this enum to route operations to the appropriate underlying HashSet, as implemented in src/gui/types/favorite.rs lines 54-78.

Adding and Removing Favorites

Programmatic API

The Favorites implementation provides insert and remove methods that accept a &FavoriteKey parameter. These methods delegate to the respective HashSet operations after dispatching based on the enum variant.

When working with the system programmatically, you can add entities as follows:

use sniffnet::gui::types::favorite::{Favorites, FavoriteKey};
use sniffnet::networking::types::host::Host;

// Assume `host` is a Host object you want to favorite
let mut fav = Favorites::default();
fav.insert(&FavoriteKey::Host(host.clone()));
// `fav.hosts()` now contains the host

Removal follows an identical pattern, calling favorites.remove(&key) to delete entries from the appropriate set.

UI Interaction and State Management

The GUI implements favorite toggling through star buttons rendered next to network entries in src/gui/pages/overview_page.rs. Each button calls FavoriteItem::star_button, which determines the current favorite state by invoking contains_host, contains_service, or contains_program depending on the entity type.

When clicked, the button emits a Message::AddOrRemoveFavorite(key, should_add) event. The main application state in src/gui/sniffer.rs handles this message:

Message::AddOrRemoveFavorite(key, should_add) => {
    if should_add { self.conf.favorites.insert(&key); }
    else { self.conf.favorites.remove(&key); }
}

This architecture cleanly separates UI events from data mutations while ensuring the configuration remains synchronized with user actions.

Querying Favorite Status

Membership testing relies on three specialized helper methods: contains_host, contains_service, and contains_program. Each delegates directly to the underlying HashSet::contains implementation, providing O(1) lookup performance.

To check if a service is favorited programmatically:

use sniffnet::gui::types::favorite::Favorites;
use sniffnet::networking::types::service::Service;

fn is_fav_service(fav: &Favorites, svc: &Service) -> bool {
    fav.contains_service(svc)
}

These query methods power both the UI star indicators in src/gui/pages/overview_page.rs and the filtering logic throughout the application.

Filtering Traffic and Reports

Overview Page Implementation

The overview page supports "Only show favorites" filtering through boolean flags in the configuration: host_favorites_filter, service_favorites_filter, and program_favorites_filter. When toggled in src/gui/sniffer.rs (lines 704-713), these flags restrict displayed entries to those present in the corresponding favorite sets.

The Favorite::get_entries method coordinates this filtering by calling specialized helpers like get_host_entries, get_service_entries, and get_program_entries. These functions build result vectors containing only favorited items when their respective filter flags are active.

Report and Inspect Views

For detailed traffic analysis, the search parameters in src/report/types/search_parameters.rs include an only_favorites boolean flag. When enabled, the report generation logic in src/report/get_report_entries.rs validates each captured packet against the favorite sets:

let is_favorite_host   = favorites.contains_host(&e.1);
let is_favorite_service = favorites.contains_service(&value.service);
let is_favorite_program = favorites.contains_program(&value.program);
let is_favorite = is_favorite_host || is_favorite_service || is_favorite_program;

Only entries satisfying this disjunction proceed through SearchParameters::match_entry, ensuring reports contain exclusively favorited traffic when the filter is active. The inspect page in src/gui/pages/inspect_page.rs provides similar UI controls for "Only show favorites".

Real-Time Notifications

Sniffnet extends the favorite system into its notification pipeline. The src/notifications/notify_and_log.rs module monitors traffic for favorited entities through the favorites_last_interval function (lines 186-204) and generates LoggedNotification::FavoriteTransmitted events when new activity occurs for tracked items.

This creates a targeted monitoring system that suppresses noise while highlighting critical network activity, allowing users to receive immediate alerts when monitored hosts or services transmit data.

Summary

  • Sniffnet's favorite system uses three HashSet instances within the Favorites struct to track hosts, services, and programs with serialization support for persistence via src/gui/types/favorite.rs.
  • The FavoriteKey enum abstracts entity types, enabling unified insertion and removal via insert() and remove() methods that pattern-match on the variant.
  • UI star buttons trigger Message::AddOrRemoveFavorite events handled in src/gui/sniffer.rs to mutate the persistent configuration state.
  • Membership testing occurs in constant time through contains_host, contains_service, and contains_program helpers.
  • Filtering applies to both the overview page (via filter flags in Conf) and report generation (via only_favorites search parameters), restricting views to favorited entities.
  • The notification system generates FavoriteTransmitted alerts in src/notifications/notify_and_log.rs when traffic involves favorited network endpoints.

Frequently Asked Questions

How does Sniffnet persist favorite hosts between application restarts?

The Favorites struct in src/gui/types/favorite.rs implements Serialize and Deserialize traits, with each HashSet annotated using #[serde(deserialize_with = "deserialize_or_default")]. This configuration saves favorites to the user's config file on disk and automatically reloads them when Sniffnet launches, maintaining state across sessions without manual intervention.

What is the time complexity for checking if a host is a favorite?

All membership checks operate in O(1) average time complexity. The contains_host, contains_service, and contains_program methods delegate directly to the underlying HashSet::contains implementation, ensuring instantaneous lookup even with thousands of tracked favorites stored in memory.

Can I filter reports to show only traffic from favorite services?

Yes. Set conf.report_search_parameters.only_favorites = true before generating the report. The get_searched_entries function in src/report/get_report_entries.rs will then verify each entry against the favorite sets using logical OR logic across hosts, services, and programs, returning only traffic involving favorited entities.

How does the UI know whether to display a filled or empty star icon?

The FavoriteItem::star_button method queries the appropriate contains_* method (depending on entity type) to determine the boolean is_favorite state. It renders the star accordingly and emits Message::AddOrRemoveFavorite(key, !is_favorite) on click, immediately toggling the favorite status in the persistent conf.favorites collection and updating the display.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →