-
Notifications
You must be signed in to change notification settings - Fork 7
/
ntp.go
90 lines (68 loc) · 1.33 KB
/
ntp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package ntp
import (
"sync"
"time"
"github.com/beevik/ntp"
"github.com/theQRL/go-qrl/pkg/config"
)
type NTP struct {
lock sync.Mutex
drift int64
lastUpdate uint64
config *config.Config
}
type NTPInterface interface {
UpdateTime() error
Time() uint64
}
func (n *NTP) UpdateTime() error {
n.lock.Lock()
defer n.lock.Unlock()
var err error
var t time.Time
for retry := 0; retry <= n.config.User.NTP.Retries; retry++ {
for _, server := range n.config.User.NTP.Servers {
t, err = ntp.Time(server)
if err != nil {
continue
}
n.drift = int64(time.Now().Unix() - t.Unix())
n.lastUpdate = uint64(t.Unix())
return nil
}
}
return err
}
func (n *NTP) Time() uint64 {
currentTime := uint64(time.Now().Unix() + n.drift)
if currentTime-n.lastUpdate > n.config.User.NTP.Refresh {
err := n.UpdateTime()
if err != nil {
// TODO: log warning here
}
}
return uint64(time.Now().Unix() + n.drift)
}
var once sync.Once
var n NTPInterface
func GetNTP() NTPInterface {
once.Do(func() {
n = &NTP{config: config.GetConfig()}
})
return n
}
type MockedNTP struct {
NTP
timestamp uint64
}
func (n *MockedNTP) SetTimestamp(timestamp uint64) {
n.timestamp = timestamp
}
func (n *MockedNTP) Time() uint64 {
return n.timestamp
}
func GetMockedNTP() *MockedNTP {
m := &MockedNTP{}
n = m
return m
}