Skip to content
API Documentation
BastionGuard™
NetworkPage.hpp
Go to the documentation of this file.
1/*
2 * BastionGuard™ Secure Connection
3 * Copyright (C) 2025–2026 Calogero Scarnà
4 * GPL-3.0
5 */
6
7#pragma once
8
9#include <gtkmm.h>
10#include <shumate/shumate.h>
11
12#include <chrono>
13#include <mutex>
14#include <string>
15#include <unordered_map>
16#include <vector>
17
18#include "../ipc/UIServer.hpp"
20
21/**
22 * Pagina Rete.
23 *
24 * Mostra una mappa reale basata su libshumate/OpenStreetMap con un marker per
25 * ogni IP contattato. La geolocalizzazione arriva da GeoResolver, mentre il
26 * rendering geografico e l'allineamento li gestisce libshumate.
27 */
28class NetworkPage : public Gtk::Box
29{
30public:
32 ~NetworkPage() override;
33
34 /** Registra una connessione per la mappa. */
35 void noteConnection(const ConnectionInfo& info);
36
37 /** Pulisci la visualizzazione. */
38 void clear();
39
40 /** Salva i pin su disco per retention 7 giorni. */
41 void saveLog() const;
42
43 /** Carica i pin da disco, scartando quelli piu' vecchi di 7 giorni. */
44 void loadLog();
45
46 /** Path del file persistente (JSONL). */
47 static std::string logPath();
48
49 /**
50 * Disegna gli archi attivi dalla posizione locale verso ogni pin
51 * attualmente aperto, piu' il puntino lampeggiante sul marker
52 * destinazione. Chiamato dall'overlay DrawingArea — pubblico perche'
53 * deve essere invocabile da una free function C-callback.
54 */
55 void drawConnectionArcs(cairo_t* cr, int width, int height);
56
57private:
58 struct Pin {
59 std::string ip;
60 std::string host;
61 std::string app_name;
62 std::string country_code;
63 std::string country_name;
64 std::string city;
65 std::string isp;
66 double lat{0.0};
67 double lon{0.0};
68 uint32_t hits{0};
69 // Timestamp monotono: usato per animazioni/decisioni runtime
70 std::chrono::steady_clock::time_point last_seen;
71 // Epoch assoluto: usato per la retention 7 giorni e la persistenza
72 int64_t last_seen_epoch{0};
73 bool geo_resolved{false};
74 };
75
76 struct Columns : public Gtk::TreeModel::ColumnRecord {
78 {
79 add(col_country);
80 add(col_city);
81 add(col_ip);
82 add(col_host);
83 add(col_app);
84 add(col_isp);
85 add(col_hits);
86 }
87
88 Gtk::TreeModelColumn<Glib::ustring> col_country;
89 Gtk::TreeModelColumn<Glib::ustring> col_city;
90 Gtk::TreeModelColumn<Glib::ustring> col_ip;
91 Gtk::TreeModelColumn<Glib::ustring> col_host;
92 Gtk::TreeModelColumn<Glib::ustring> col_app;
93 Gtk::TreeModelColumn<Glib::ustring> col_isp;
94 Gtk::TreeModelColumn<uint32_t> col_hits;
95 };
96
98 Glib::RefPtr<Gtk::ListStore> m_store;
99 Gtk::TreeView m_treeView;
100 Gtk::ScrolledWindow m_scroll;
101 Gtk::Box m_mapHost{Gtk::Orientation::VERTICAL, 0};
102 Gtk::Label m_headerLabel;
103 Gtk::Label m_summaryLabel;
104 Gtk::Button m_clearBtn;
105
106 // libshumate (C API) integrato dentro gtkmm
107 GtkWidget* m_simpleMap{nullptr};
108 ShumateViewport* m_viewport{nullptr};
109 ShumateMarkerLayer* m_markerLayer{nullptr};
110
111 // overlay e card hover
112 GtkWidget* m_mapOverlay{nullptr};
113 GtkWidget* m_hoverCard{nullptr};
114 GtkWidget* m_hoverCardTitle{nullptr};
115 GtkWidget* m_hoverCardBody{nullptr};
117 std::chrono::steady_clock::time_point m_lastUserViewportInteraction{};
118
119 // ── Origine PC locale + archi di connessione (stile Little Snitch) ──
120 // m_selfLat/m_selfLon: posizione geografica del PC stesso, risolta
121 // tramite GeoResolver::resolve_self() (chiamata ip-api senza IP).
122 // Viene mostrata come marker blu fisso sulla mappa. Le linee sulla
123 // overlay drawing area partono da qui verso ogni pin attivo.
124 double m_selfLat{0.0};
125 double m_selfLon{0.0};
126 bool m_selfResolved{false};
127 GtkWidget* m_mapFxArea{nullptr}; // drawing area overlay usata per gli archi
128
129 // Timer di animazione (pulse dei marker destinazione + redraw archi).
130 // 60 Hz e' troppo per questo uso — 15 Hz (66 ms) e' piacevole e leggero.
133
134 // Retention log: pin piu' vecchi di 7 giorni vengono scartati al
135 // loadLog(). Runtime: accumuliamo senza mai scartare pin "freschi".
136 //
137 // NOTA: niente piu' finestra "connessioni aperte": l'utente ha
138 // chiesto di tenere TUTTI i pin visibili sulla mappa (non solo
139 // quelli degli ultimi N secondi). Lo storico sparisce solo quando
140 // davvero vecchio.
141 static constexpr int64_t kRetentionSeconds = 7 * 24 * 3600; // 7 giorni
142
143 // Chiave = IP: pin aggregato
144 mutable std::mutex m_mu;
145 std::unordered_map<std::string, Pin> m_pins;
146 std::unordered_map<std::string, Gtk::TreeModel::iterator> m_rows;
147
148 // Dispatcher per callback geo resolve (worker -> UI thread)
149 Glib::Dispatcher m_geoDispatcher;
150 std::mutex m_pendingMu;
151 std::vector<std::pair<std::string, bsc::ui_util::GeoEntry>> m_pendingGeo;
152
153 void buildUI();
154 void buildMapWidget();
155 void rebuildMapMarkers();
156 GtkWidget* createMarkerWidget(const Pin& pin);
157 GtkWidget* createSelfMarkerWidget();
158 GtkWidget* createHoverCard();
159 void showHoverCard(const std::string& country_code,
160 const std::string& country_name,
161 const std::string& city,
162 const std::string& ip,
163 const std::string& host,
164 const std::string& app_name,
165 const std::string& isp,
166 uint32_t hits);
167 void hideHoverCard();
168 void maybeRecenterMap(const std::vector<Pin>& pins);
169 void onGeoResolved();
170 void updateSummary();
171 void updateRow(const Pin& pin);
173 bool shouldHoldUserViewport() const;
174
175 // Kicks off la risoluzione della posizione del PC locale (lazy,
176 // non blocca). Al completamento rebuilda i marker per aggiungere
177 // il punto blu di origine.
178 void requestSelfLocation();
179
180 // Redraw dell'overlay archi (chiamato dal pulse timer ~15 Hz).
181 void triggerFxRedraw();
182};
GtkWidget * m_simpleMap
void noteConnection(const ConnectionInfo &info)
Gtk::Label m_headerLabel
bool shouldHoldUserViewport() const
guint m_hoverHideSource
static constexpr int64_t kRetentionSeconds
Glib::RefPtr< Gtk::ListStore > m_store
std::unordered_map< std::string, Gtk::TreeModel::iterator > m_rows
GtkWidget * m_hoverCardTitle
std::vector< std::pair< std::string, bsc::ui_util::GeoEntry > > m_pendingGeo
Gtk::TreeView m_treeView
GtkWidget * createSelfMarkerWidget()
guint m_pulseTimerId
void drawConnectionArcs(cairo_t *cr, int width, int height)
std::chrono::steady_clock::time_point m_lastUserViewportInteraction
void rebuildMapMarkers()
Gtk::Label m_summaryLabel
Glib::Dispatcher m_geoDispatcher
void updateRow(const Pin &pin)
Gtk::Box m_mapHost
Columns m_columns
void showHoverCard(const std::string &country_code, const std::string &country_name, const std::string &city, const std::string &ip, const std::string &host, const std::string &app_name, const std::string &isp, uint32_t hits)
GtkWidget * createHoverCard()
GtkWidget * m_mapFxArea
void requestSelfLocation()
void onGeoResolved()
void noteUserViewportInteraction()
std::mutex m_mu
GtkWidget * m_hoverCard
void hideHoverCard()
GtkWidget * m_mapOverlay
void buildMapWidget()
void saveLog() const
ShumateViewport * m_viewport
ShumateMarkerLayer * m_markerLayer
GtkWidget * createMarkerWidget(const Pin &pin)
std::mutex m_pendingMu
Gtk::ScrolledWindow m_scroll
Gtk::Button m_clearBtn
void maybeRecenterMap(const std::vector< Pin > &pins)
void triggerFxRedraw()
std::unordered_map< std::string, Pin > m_pins
static std::string logPath()
void updateSummary()
GtkWidget * m_hoverCardBody
Gtk::TreeModelColumn< Glib::ustring > col_country
Gtk::TreeModelColumn< Glib::ustring > col_app
Gtk::TreeModelColumn< uint32_t > col_hits
Gtk::TreeModelColumn< Glib::ustring > col_isp
Gtk::TreeModelColumn< Glib::ustring > col_host
Gtk::TreeModelColumn< Glib::ustring > col_city
Gtk::TreeModelColumn< Glib::ustring > col_ip
int64_t last_seen_epoch
std::string city
std::string country_name
std::chrono::steady_clock::time_point last_seen
std::string isp
std::string app_name
std::string country_code
std::string host