Skip to content

Commit

Permalink
Some small improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewLester committed Jul 6, 2023
1 parent 02be458 commit 312df37
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 29 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ NTPal is an in-development, incomplete, and rough around the edges implementatio

## Code Credits

The code for NTPal is _very_ similar to pseudocode provided in the [NTPv4 RFC](https://datatracker.ietf.org/doc/html/rfc5905), which is nicely documented and made for a good rewriting experience. Certain changes were made based on more recent additions to projects such as [ntpd](https://github.com/ntp-project/ntp), [chrony](https://github.com/mlichvar/chrony), and others. Additionally, some care was taken to map the program's requirements into better-fit Golang structures, but there's still some room for improvement (especially regarding race conditions).
The code for NTPal is _very_ similar to pseudocode provided in the [NTPv4 RFC](https://datatracker.ietf.org/doc/html/rfc5905), which is nicely documented and made for a good rewriting experience. Certain changes were made based on more recent additions to projects such as [ntpd](https://github.com/ntp-project/ntp), [chrony](https://github.com/mlichvar/chrony), and others. Additionally, some care was taken to map the program's requirements into better-fit Golang structures, but there's room for improvement (especially regarding race conditions).

## Usage

Expand All @@ -25,6 +25,12 @@ NTPal uses a configuration format similar to the [standard `ntpd` config](https:
- `server <address> [key _key_] [burst] [iburst] [version _version_] [prefer] [minpoll _minpoll_] [maxpoll _maxpoll_]`
- `driftfile <path>`

Some environment variables are also available to configure the application's runtime and logging:

- `SYMMETRIC`: Set to "1" to allow symmetric active servers to connect.
- `INFO`: Set to "1" to print periodic system information logs.
- `DEBUG`: Set to "1" to print timeseries clock statistics meant for graphing.

### NTPal &mdash; Query

NTPal supports a simpler "query" flag to simply obtain your device's time offset from an NTP server. Accessible via `--query` or `-q`, 5 messages are sent in an attempt to obtain the best measurement possible. This command functions almost identically to the `sntp` command shipped with OSX, though NTPal has far less functionality.
Expand Down
1 change: 0 additions & 1 deletion fly.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ kill_timeout = 5
NTP_PORT = "123"
NTP_HOST = "fly-global-services"
REPORT_PORT = "8080"
ENABLED = "1"
INFO = "1"

[[mounts]]
Expand Down
9 changes: 3 additions & 6 deletions internal/templates/templates/index.tmpl.html
Original file line number Diff line number Diff line change
Expand Up @@ -289,26 +289,23 @@ <h2>According to this server,</h2>
}

const { offset } = minDelayAttempt;
let serverTime = new Date((Date.now() / 1e3 + offset) * 1e3);
let serverTime = new Date(Date.now() + offset / 1e3);

// Wait for the second to hit
await sleep(1e3 - (serverTime % 1e3));
setInterval(() => {
const serverTime = new Date(
(Date.now() / 1e3 + offset) * 1e3
);
const serverTime = new Date(Date.now() + offset / 1e3);
displayTime(serverTime);
}, 1000);

serverTime = new Date((Date.now() / 1e3 + offset) * 1e3);
serverTime = new Date(Date.now() + offset / 1e3);
displayTime(serverTime);

const offsetMessage = offset < 0 ? 'ahead' : 'behind';
elems.offset.textContent = `${offsetMessage} by ${Math.abs(
offset
).toFixed(3)} seconds`; // We do have up to microsecond precision, but it's not great...
elems.offset.classList.add('done');

elems.time.classList.add('done');
}

Expand Down
29 changes: 22 additions & 7 deletions pkg/ntp/ntp.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const PORT = 123 // NTP port number
const VERSION byte = 4 // NTP version number
const TOLERANCE = 15e-6 //frequency tolerance PHI (s/s)
const MINPOLL int8 = 6 //minimum poll exponent (64 s)
const MAXPOLL int8 = 17 // maximum poll exponent (36 h)
const MAXPOLL int8 = 16 // maximum poll exponent (36 h)
const MAXDISP float64 = 16 // maximum dispersion (16 s)
const MINDISP = 0.005 // minimum dispersion increment (s)
const NOSYNC byte = 0x3 // leap unsync
Expand Down Expand Up @@ -696,8 +696,10 @@ func (system *NTPSystem) sendPoll(association *Association) {
if err != nil {
log.Fatal("Invalid address: ", association.hostname)
}
if association.srcaddr == addr {
hpoll++
}
association.srcaddr = addr
hpoll++
association.unreach = -1
}
association.unreach++
Expand Down Expand Up @@ -768,9 +770,20 @@ func (system *NTPSystem) receive(packet ReceivePacket) *TransmitPacket {
// else if (auth == A_ERROR)
// fast_xmit(r, M_SERV, A_CRYPTO);
// return; /* M_SERV packet sent */
case NEWPS:
if !isSymmetricEnabled() {
return nil
}

association = &Association{
ReceivePacket: packet,
hmode: SYMMETRIC_PASSIVE,
ephemeral: true,
}
system.clear(association, INIT)
system.associations = append(system.associations, association)
case PROC:
break
case DSCRD:
default:
return nil
}

Expand Down Expand Up @@ -1086,6 +1099,9 @@ func (system *NTPSystem) clockFilter(association *Association, offset float64, d
for i := NSTAGE - 1; i > 0; i-- {
association.f[i] = association.f[i-1]
association.f[i].disp += PHI * (float64(system.clock.t) - association.t)
if association.f[i].disp > MAXDISP {
association.f[i].disp = MAXDISP
}
f[i] = association.f[i]
}
association.f[0].t = system.clock.t
Expand All @@ -1107,7 +1123,7 @@ func (system *NTPSystem) clockFilter(association *Association, offset float64, d
association.disp = 0
association.jitter = 0
for i := NSTAGE - 1; i >= 0; i-- {
association.disp += f[i].disp / math.Pow(2, float64(i+1))
association.disp = 0.5 * (association.disp + f[i].disp)
if i < m {
association.jitter += math.Pow((f[0].offset - f[i].offset), 2)
}
Expand Down Expand Up @@ -1443,8 +1459,7 @@ func (system *NTPSystem) clockUpdate(association *Association) {
}
system.reftime = association.Reftime
system.rootdelay = association.Rootdelay + association.delay
dtemp := math.Sqrt(math.Pow(association.jitter, 2) + math.Pow(system.jitter, 2))
dtemp += math.Max(association.disp+PHI*(float64(system.clock.t)-association.t)+
dtemp := math.Max(association.disp+system.jitter+PHI*(float64(system.clock.t)-association.t)+
math.Abs(association.offset), MINDISP)
system.rootdisp = association.Rootdisp + dtemp
/*
Expand Down
17 changes: 7 additions & 10 deletions pkg/ntp/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@ func stepTime(offset float64) {
Sec -= unixEraOffset

info("CURRENT:", NTPTimestampToTime(systemTime), "STEPPING TO:", NTPTimestampToTime(ntpTime), "OFFSET WAS:", offset)
if shouldSetTime() {
err := settimeofday.Settimeofday(Sec, Usec)
if err != nil {
info("SETTIMEOFDAYERR:", err)
}

err := settimeofday.Settimeofday(Sec, Usec)
if err != nil {
info("SETTIMEOFDAYERR:", err)
}
}

Expand All @@ -50,10 +49,8 @@ func adjustTime(offset float64) {
Usec += 1e6
}

if shouldSetTime() {
err := adjtime.Adjtime(Sec, Usec)
if err != nil {
info("ADJTIME ERROR:", err, "offset:", offset)
}
err := adjtime.Adjtime(Sec, Usec)
if err != nil {
info("ADJTIME ERROR:", err, "offset:", offset)
}
}
8 changes: 4 additions & 4 deletions pkg/ntp/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ import (
"os"
)

func shouldSetTime() bool {
return os.Getenv("ENABLED") == "1"
}

func info(args ...any) {
if isInfo() {
fmt.Println(args...)
Expand All @@ -28,3 +24,7 @@ func isInfo() bool {
func isDebug() bool {
return os.Getenv("DEBUG") == "1"
}

func isSymmetricEnabled() bool {
return os.Getenv("SYMMETRIC") == "1"
}

0 comments on commit 312df37

Please sign in to comment.