Browse Source

ntp_node_time: фикс ложных докладов о дрейфе часов

check_drift() вызывался с сырой разницей часов между узлами, а не
с изменением offset со временем. При разнице часов между машинами
в 229 секунд это давало спам WARN на каждый TIME_SYNC обмен.

Теперь: первый обмен сохраняет offset без проверки; последующие
сравнивают дельту и warn только при реальном дрейфе (изменении offset).
topo_upd
Evgeny 2 months ago
parent
commit
fdaaa41010
  1. 22
      src/ntp_node_time.c
  2. 1
      src/ntp_node_time.h

22
src/ntp_node_time.c

@ -86,18 +86,19 @@ static struct NTP_NODE_PEER* add_peer(struct NTP_NODE_TIME* np, uint64_t node_id
struct NTP_NODE_PEER* p = &np->peers[np->peer_count]; struct NTP_NODE_PEER* p = &np->peers[np->peer_count];
p->node_id = node_id; p->node_id = node_id;
p->offset_us = 0; p->offset_us = 0;
p->has_offset = 0;
np->peer_count++; np->peer_count++;
return p; return p;
} }
static void check_drift(uint64_t node_id, int64_t offset_us) { static void check_drift(uint64_t node_id, int64_t offset_delta_us) {
int64_t abs_us = offset_us < 0 ? -offset_us : offset_us; int64_t abs_us = offset_delta_us < 0 ? -offset_delta_us : offset_delta_us;
if (abs_us > NTP_NODE_DRIFT_ERROR_US) { if (abs_us > NTP_NODE_DRIFT_ERROR_US) {
DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "NTP_node: clock drift >10s with node %012llx: %lldus", DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "NTP_node: clock offset changed by >10s with node %012llx: %lldus",
(unsigned long long)node_id, (long long)offset_us); (unsigned long long)node_id, (long long)offset_delta_us);
} else if (abs_us > NTP_NODE_DRIFT_WARN_US) { } else if (abs_us > NTP_NODE_DRIFT_WARN_US) {
DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "NTP_node: clock drift >2s with node %012llx: %lldus", DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "NTP_node: clock offset changed by >2s with node %012llx: %lldus",
(unsigned long long)node_id, (long long)offset_us); (unsigned long long)node_id, (long long)offset_delta_us);
} }
} }
@ -135,9 +136,14 @@ static void ntp_node_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
struct NTP_NODE_TIME* np = &inst->ntp_node; struct NTP_NODE_TIME* np = &inst->ntp_node;
struct NTP_NODE_PEER* peer = find_peer(np, conn->peer_node_id); struct NTP_NODE_PEER* peer = find_peer(np, conn->peer_node_id);
if (!peer) peer = add_peer(np, conn->peer_node_id); if (!peer) peer = add_peer(np, conn->peer_node_id);
if (peer) peer->offset_us = peer_offset; if (!peer) return;
check_drift(conn->peer_node_id, peer_offset); if (peer->has_offset) {
int64_t offset_delta = peer_offset - peer->offset_us;
check_drift(conn->peer_node_id, offset_delta);
}
peer->offset_us = peer_offset;
peer->has_offset = 1;
int was_unsynced = !ntp_time_is_synced(inst); int was_unsynced = !ntp_time_is_synced(inst);

1
src/ntp_node_time.h

@ -17,6 +17,7 @@ struct UTUN_INSTANCE;
struct NTP_NODE_PEER { struct NTP_NODE_PEER {
uint64_t node_id; uint64_t node_id;
int64_t offset_us; // my_time_recv - peer_time (positive = my clock ahead) int64_t offset_us; // my_time_recv - peer_time (positive = my clock ahead)
int has_offset; // first offset already stored, subsequent deltas are real drift
}; };
struct NTP_NODE_TIME { struct NTP_NODE_TIME {

Loading…
Cancel
Save