ntp: don't send packets with RX equal to TX

Before sending an NTP packet, check whether the TX timestamp is not
equal to the RX timestamp. If it is, generate a new TX timestamp and try
again. This is extremely unlikely to happen in normal operation, but it
is needed for reliable detection of the interleaved mode.
This commit is contained in:
Miroslav Lichvar 2017-01-10 11:30:52 +01:00
parent f2f834e7e7
commit 061579ec28

View file

@ -956,7 +956,8 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
frequency all along */ frequency all along */
UTI_TimespecToNtp64(&local_receive, &message.receive_ts, &ts_fuzz); UTI_TimespecToNtp64(&local_receive, &message.receive_ts, &ts_fuzz);
/* Prepare random bits which will be added to the transmit timestamp. */ do {
/* Prepare random bits which will be added to the transmit timestamp */
UTI_GetNtp64Fuzz(&ts_fuzz, precision); UTI_GetNtp64Fuzz(&ts_fuzz, precision);
/* Transmit - this our local time right now! Also, we might need to /* Transmit - this our local time right now! Also, we might need to
@ -969,11 +970,11 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
length = NTP_NORMAL_PACKET_LENGTH; length = NTP_NORMAL_PACKET_LENGTH;
/* Authenticate the packet if needed */ /* Authenticate the packet */
if (auth_mode == AUTH_SYMMETRIC || auth_mode == AUTH_MSSNTP) { if (auth_mode == AUTH_SYMMETRIC || auth_mode == AUTH_MSSNTP) {
/* Pre-compensate the transmit time by approx. how long it will /* Pre-compensate the transmit time by approximately how long it will
take to generate the authentication data. */ take to generate the authentication data */
local_transmit.tv_nsec += auth_mode == AUTH_SYMMETRIC ? local_transmit.tv_nsec += auth_mode == AUTH_SYMMETRIC ?
KEY_GetAuthDelay(key_id) : NSD_GetAuthDelay(key_id); KEY_GetAuthDelay(key_id) : NSD_GetAuthDelay(key_id);
UTI_NormaliseTimespec(&local_transmit); UTI_NormaliseTimespec(&local_transmit);
@ -1008,6 +1009,11 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
&message.transmit_ts, &ts_fuzz); &message.transmit_ts, &ts_fuzz);
} }
/* Avoid sending messages with non-zero transmit timestamp equal to the
receive timestamp to allow reliable detection of the interleaved mode */
} while (!UTI_CompareNtp64(&message.transmit_ts, &message.receive_ts) &&
!UTI_IsZeroNtp64(&message.transmit_ts));
ret = NIO_SendPacket(&message, where_to, from, length, local_tx != NULL); ret = NIO_SendPacket(&message, where_to, from, length, local_tx != NULL);
if (local_tx) { if (local_tx) {