Skip to content

Latest commit

 

History

History
101 lines (65 loc) · 2.61 KB

README.md

File metadata and controls

101 lines (65 loc) · 2.61 KB

HTP

HTP uses time information present in HTTP headers to determine the clock offset between two machines. It can be used to synchronize the local clock using a trusted HTTP(S) server, or to determine the time of the remote machine.

Important

If NTP is available, use it instead. I developed this application to be able to synchronize my computer's clock in a network that blocked NTP packets.

Installation

Download the binary for your platform from the releases page.

Or install it with go:

go install github.com/danroc/htp/cmd/htp@latest

Building

To build the main application, run:

go build ./cmd/htp

Algorithm

Suppose that T is the correct time (remote time) and our local time is offset by θ (thus local time is T + θ).

To approximate θ, we perform these steps:

  1. (A, local) sends a request to (B, remote) at t₀ (local clock)
  2. (B) receives and answers (A)'s request at t₁ (remote clock)
  3. (A) receives (B)'s answer at t₂ (local clock)

These steps are represented in the following diagram:

            t₁
(B) --------^--------> T
           / \
          /   \
(A) -----^-----v-----> T + θ
         t₀    t₂

Bringing t₁ to the local time (between t₀ and t₂):

t₀ < t₁ + θ < t₂ ⇒ t₀ - t₁ < θ < t₂ - t₁

So,

  • θ > t₀ - t₁
  • θ < t₂ - t₁

But we must use ⌊t₁⌋ instead of t₁ in our calculations because it is the only time information present in the HTTP response header.

Since t₁ ∈ [⌊t₁⌋, ⌊t₁⌋ + 1), then:

  • θ > t₀ - ⌊t₁⌋ - 1
  • θ < t₂ - ⌊t₁⌋

Observe that the closer t₁ is to ⌊t₁⌋ or ⌊t₁⌋ + 1, smaller is the error in the second or first equation above, respectively.

We can repeat the above procedure to improve our estimate of θ:

  • θ⁻ = MAX(θ⁻, t₀ - ⌊t₁⌋ - 1)
  • θ⁺ = MIN(θ⁺, t₂ - ⌊t₁⌋)
  • θ = (θ⁺ + θ⁻)/2

The ideal delay d to wait before sending the next request is calculated so that the next value of t₁ is close to a "full" second:

t₂ + d + (t₂ - t₀)/2 - θ = ⌊t₁⌋ + k, k ∈ ℤ

⇒ d = ⌊t₁⌋ + k + θ - t₂ - (t₂ - t₀)/2 mod 1

⇒ d = θ - t₂ - (t₂ - t₀)/2 mod 1

Where:

  • (t₂ - t₀) is an estimation of the round-trip time (RTT).
  • - θ converts from local to remote time.

Alternatives

  • One-liner:

    date -s "$(curl -fsSLI https://www.google.com | grep -i "Date: " | cut -d" " -f2-)"
  • Time over HTTPS

  • htpdate