# План: Виправлення діагностики обривів мережі

## Огляд
На основі результатів дослідження (`research.md`) виявлено 10 проблем у логіці пінгування (`pinger.rs`), які призводять до того, що після обриву зв'язку деякі хости на трасі тривалий час не оновлюються, і програма неправильно визначає точку обриву. Цей план описує кроки з виправлення алгоритму визначення обриву шляхом додавання таймштампів свіжості даних, покращення логіки знаходження шлюзу, паралелізації DNS-розв'язки та інвалідації кешу ICMP-запитів.

## Зміни в архітектурі
*   **`HostStatus` (`src/model/status.rs`)**: Буде додано нове поле `last_updated: Option<Instant>` для фіксації часу останнього пінгу. Встановлення `alive` буде перенесено в метод `add_sample()` для забезпечення атомності оновлень (разом з `last_updated`).
*   **Головний цикл `pinger_task` (`src/logic/pinger.rs`)**: 
    *   Створення та розв'язка доменних імен (DNS) у ICMP requestor-ах виконуватиметься асинхронно та паралельно (`tokio::spawn`), щоб відсутність мережі/повільний DNS не блокував весь цикл.
    *   Діагностика: Перевірка "Local Interface" буде розширена на випадок падіння першого хопа маршруту (шлюзу).
    *   При наявності обривів будуть враховуватись лише "свіжі" дані (віком до 15-30 секунд), а хопи з відсутнім статусом ігноруватимуться.
*   **Traceroute (`src/logic/pinger.rs`)**: Буде додано механізм перезапуску traceroute, коли хост змінює стан з alive на down (для виявлення нових маршрутів після зміни інтерфейсу).

## Етапи реалізації

- [x] **Крок 1: Оновлення моделі `HostStatus`**
    - [x] У `src/model/status.rs` додати `last_updated: Option<Instant>` (з атрибутом `#[serde(skip, default)]`).
    - [x] Перенести оновлення `self.alive = rtt_ms.is_finite()` або передавати параметр в `add_sample(&mut self, rtt_ms: f64, alive: bool)` і встановлювати `last_updated = Some(Instant::now())`.
    - [x] Оновити ініціалізацію `streak`: новий хоп повинен мати такий стан, який не викличе хибне спрацьовування "broken" до першого пінгу.

- [x] **Крок 2: Паралелізація DNS та ICMP у `pinger_task`**
    - [x] У `src/logic/pinger.rs` переписати цикл по `addresses_to_ping`, винісши отримання/створення `IcmpEchoRequestor` (включно зі зверненням до DNS: `tokio::net::lookup_host`) безпосередньо у `tokio::spawn`.
    - [x] Щоб це працювало, потрібно шарити мапу `requestors` за допомогою `Arc<tokio::sync::Mutex<HashMap<..>>>` або `Arc<std::sync::Mutex<..>>`. Захоплювати lock лише для перевірки/додавання, а не для `send()`.

- [x] **Крок 3: Інвалідація кешу requestor'ів**
    - [x] Якщо під час асинхронного `send()` (`tokio::spawn`) виникає `Err(e)` або якщо DNS не може розпізнати адресу, видаляти запис для цього хоста з `requestors` (щоб наступного разу створити заново, на випадок зміни інтерфейсу).

- [x] **Крок 4: Вдосконалення Failure Deduction (діагностики)**
    - [x] У блоці "Failure deduction logic" (`src/logic/pinger.rs`) змінити перевірку логіки "Local Interface". Додати: `if let Some(first_hop) = state_lock.statuses.get(&path[0]) { ... }`. Якщо перший хоп неживий та свіжий — це "Local Interface".
    - [x] Перевіряти `last_updated`: дані старші за 15 секунд (або `3 * compute_interval(Fast)`) вважати застарілими та прирівнювати до розриву зв'язку.
    - [x] Для невідомих хопів у подвійному циклі (через `path`) та перевірці `all_further_broken` вважати відсутність статусу в мапі (або застарілий статус) еквівалентним `all_further_broken = false` (щоб не кидати хибні діагнози на півдорозі traceroute).

- [x] **Крок 5: Адаптація швидкості traceroute (опціонально)**
    - [x] Додати логіку: якщо цільовий хост щойно став DOWN (а до цього був ALIVE), скинути таймер `last_trace_times` для нього, щоб traceroute запустився негайно (враховуючи зміну маршруту, напр. WAN failover).

- [x] **Крок 6: Тестування та Рефакторинг**
    - [x] Оновити всі unit-тести у `src/logic/pinger_tests.rs`, де симулюється зміна статусу або створення `HostStatus`.
    - [x] Перевірити реальну поведінку при вимкненні Wi-Fi — UI повинно за лічені секунди змінити статус на `ОБРИВ НА (Локальний інтерфейс)`.

## Критерії успіху
1. Проект компілюється без помилок та попереджень (`cargo check`, `cargo fmt`, `cargo clippy`).
2. При відключенні мережі програма миттєво (за 2-6 сек) діагностує `ОБРИВ НА (Локальний інтерфейс)`.
3. UI не "зависає", якщо додано адреси-домени (DNS) при відсутності інтернет-зв'язку.
4. Після перемикання Інтернету (напр. Wi-Fi на мобільний через USB модем) пінги успішно відновлюються без потреби в перезапуску програми (завдяки інвалідації застарілих ICMP-сокетів у кеші).
5. Unit-тести для `pinger` та `status` проходять успішно.
