Процесс довольно сложный, но обратите внимание, что синхронизация NTP - это диалог, и, как вы подозреваете, ему нужно отработать время прохождения сигнала в обоих направлениях, чтобы эффективно синхронизировать его, принимая во внимание, сколько времени занимают пакеты.
Хотя клиент может не знать точное время, когда он запрашивает обновление времени, он знает, по крайней мере, когда он отправил пакет. Сервер знает точное время получения пакета, а также точное время отправки ответа. Клиент знает время между временем отправки пакета и получением ответа.
Таким образом, из этих чисел легко вычислить правильное время при условии, что задержка постоянна во время разговора.
Конечно, это не всегда согласуется, поэтому несколько серверов обычно настраиваются так, что ошибки могут усредняться, а клиент хранит информацию отслеживания состояния, чтобы он мог игнорировать любые сумасшедшие результаты.
Википедия - хороший источник деталей.