# NTP Time ## 1. Назначение SNTP-клиент (RFC 5905) для синхронизации системного времени с внешними NTP-серверами. Модуль вычисляет смещение `offset_us = local_time - ntp_time` (положительное = локальные часы спешат) и позволяет везде в коде использовать `ntp_time_get_us()` вместо `gettimeofday()` для получения скорректированного времени. Без коррекции времени невозможна корректная работа node-to-node синхронизации (`ntp_node_time`) и оценка RTT/jitter в ETCP. ## 2. Как пользоваться `ntp_time_init()` читает список NTP-серверов из конфига (`global.ntp_servers`) и запускает периодический опрос через uasync-таймер. Опрос — по одному серверу за цикл с round-robin, при неудаче перебирает остальные. Интервал ресинка задаётся через `ntp_resync_interval` (по умолчанию 3600с). Первый запрос — сразу после init. При успешной синхронизации вызывается `ntp_node_sync_peers()` для рассылки времени соседним узлам. Для тестов: `ntp_time_set_test_addr()` задаёт прямой адрес NTP-сервера (IP:port), минуя DNS-резолвинг. **Нюансы:** - Если `ntp_enabled=0` или серверов нет, модуль не опрашивает, `ntp_time_get_us()` возвращает локальное время - Если синхронизации не было, то же самое — возвращается `gettimeofday()` без коррекции - SNTP (simplified NTP) — использует только один запрос-ответ, без сложной фильтрации ## 3. API **Структуры:** - `struct NTP_TIME` — состояние синхронизации: флаг synced, offset_us, last_sync_tb, список серверов, текущий индекс и таймер **Функции:** - `ntp_time_init(instance)` — читает конфиг, выделяет массив серверов, запускает первый sync-таймер - `ntp_time_destroy(instance)` — отменяет таймер, освобождает память серверов - `ntp_time_set_test_addr(ntp, ip, port)` — задать NTP-сервер напрямую (без DNS) для тестов - `ntp_time_get_us(instance)` — скорректированное время в микросекундах (если synced), иначе `gettimeofday()` - `ntp_time_get_seconds(instance)` — скорректированное время в секундах (time_t) - `ntp_time_is_synced(instance)` — true если была успешная синхронизация