Skip to content

Commit 58967db

Browse files
committed
fix/timesync: Ensure that auto-update waits for time sync
- Added check to not attempt auto update if time sync is needed and not yet successful (delays 30 second to recheck). - Added resync of time when DHCP or link state changes if online - Added conditional* fallback from configured* NTP servers to the IP-named NTP servers, and then to the DNS named ones if that fails - Added conditional* fallback from the configured* HTTP servers to the default DNS named ones. - Uses the configuration* option for how many queries to run in parallel - Added known static IPs for time servers (in case DNS resolution isn't up yet) - Added time.cloudflare.com to fall-back NTP servers * Note: The UI for configuring many of these things doesn't exist yet, but the defaults are reasonable Fix lint issue Delete trailing tabs Added fallback to NTP via hostnames Fixes lint issue and logs the resultant time (and mode)
1 parent 55fbd6c commit 58967db

File tree

5 files changed

+69
-27
lines changed

5 files changed

+69
-27
lines changed

internal/network/netif.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ type NetworkInterfaceOptions struct {
4848
DefaultHostname string
4949
OnStateChange func(state *NetworkInterfaceState)
5050
OnInitialCheck func(state *NetworkInterfaceState)
51-
OnDhcpLeaseChange func(lease *udhcpc.Lease)
51+
OnDhcpLeaseChange func(lease *udhcpc.Lease, state *NetworkInterfaceState)
5252
OnConfigChange func(config *NetworkConfig)
5353
NetworkConfig *NetworkConfig
5454
}
@@ -94,7 +94,7 @@ func NewNetworkInterfaceState(opts *NetworkInterfaceOptions) (*NetworkInterfaceS
9494
_ = s.updateNtpServersFromLease(lease)
9595
_ = s.setHostnameIfNotSame()
9696

97-
opts.OnDhcpLeaseChange(lease)
97+
opts.OnDhcpLeaseChange(lease, s)
9898
},
9999
})
100100

internal/timesync/ntp.go

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,32 @@ import (
99
"github.com/beevik/ntp"
1010
)
1111

12-
var defaultNTPServers = []string{
12+
var defaultNTPServerIPs = []string{
13+
// These servers are known by static IP and as such don't need DNS lookups
14+
// These are from Google and Cloudflare since if they're down, the internet
15+
// is broken anyway
16+
"162.159.200.1", // time.cloudflare.com IPv4
17+
"162.159.200.123", // time.cloudflare.com IPv4
18+
"2606:4700:f1::1", // time.cloudflare.com IPv6
19+
"2606:4700:f1::123", // time.cloudflare.com IPv6
20+
"216.239.35.0", // time.google.com IPv4
21+
"216.239.35.4", // time.google.com IPv4
22+
"216.239.35.8", // time.google.com IPv4
23+
"216.239.35.12", // time.google.com IPv4
24+
"2001:4860:4806::", // time.google.com IPv6
25+
"2001:4860:4806:4::", // time.google.com IPv6
26+
"2001:4860:4806:8::", // time.google.com IPv6
27+
"2001:4860:4806:c::", // time.google.com IPv6
28+
}
29+
30+
var defaultNTPServerHostnames = []string{
31+
// should use something from https://github.com/jauderho/public-ntp-servers
1332
"time.apple.com",
1433
"time.aws.com",
1534
"time.windows.com",
1635
"time.google.com",
17-
"162.159.200.123", // time.cloudflare.com IPv4
18-
"2606:4700:f1::123", // time.cloudflare.com IPv6
19-
"0.pool.ntp.org",
20-
"1.pool.ntp.org",
21-
"2.pool.ntp.org",
22-
"3.pool.ntp.org",
36+
"time.cloudflare.com",
37+
"pool.ntp.org",
2338
}
2439

2540
func (t *TimeSync) queryNetworkTime(ntpServers []string) (now *time.Time, offset *time.Duration) {

internal/timesync/timesync.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ func (t *TimeSync) Sync() error {
158158
var (
159159
now *time.Time
160160
offset *time.Duration
161+
log zerolog.Logger
161162
)
162163

163164
metricTimeSyncCount.Inc()
@@ -166,54 +167,54 @@ func (t *TimeSync) Sync() error {
166167

167168
Orders:
168169
for _, mode := range syncMode.Ordering {
170+
log = t.l.With().Str("mode", mode).Logger()
169171
switch mode {
170172
case "ntp_user_provided":
171173
if syncMode.Ntp {
172-
t.l.Info().Msg("using NTP custom servers")
174+
log.Info().Msg("using NTP custom servers")
173175
now, offset = t.queryNetworkTime(t.networkConfig.TimeSyncNTPServers)
174176
if now != nil {
175-
t.l.Info().Str("source", "NTP").Time("now", *now).Msg("time obtained")
176177
break Orders
177178
}
178179
}
179180
case "ntp_dhcp":
180181
if syncMode.Ntp {
181-
t.l.Info().Msg("using NTP servers from DHCP")
182+
log.Info().Msg("using NTP servers from DHCP")
182183
now, offset = t.queryNetworkTime(t.dhcpNtpAddresses)
183184
if now != nil {
184-
t.l.Info().Str("source", "NTP DHCP").Time("now", *now).Msg("time obtained")
185185
break Orders
186186
}
187187
}
188188
case "ntp":
189189
if syncMode.Ntp && syncMode.NtpUseFallback {
190-
t.l.Info().Msg("using NTP fallback")
191-
now, offset = t.queryNetworkTime(defaultNTPServers)
190+
log.Info().Msg("using NTP fallback IPs")
191+
now, offset = t.queryNetworkTime(defaultNTPServerIPs)
192+
if now == nil {
193+
log.Info().Msg("using NTP fallback hostnames")
194+
now, offset = t.queryNetworkTime(defaultNTPServerHostnames)
195+
}
192196
if now != nil {
193-
t.l.Info().Str("source", "NTP fallback").Time("now", *now).Msg("time obtained")
194197
break Orders
195198
}
196199
}
197200
case "http_user_provided":
198201
if syncMode.Http {
199-
t.l.Info().Msg("using HTTP custom URLs")
202+
log.Info().Msg("using HTTP custom URLs")
200203
now = t.queryAllHttpTime(t.networkConfig.TimeSyncHTTPUrls)
201204
if now != nil {
202-
t.l.Info().Str("source", "HTTP").Time("now", *now).Msg("time obtained")
203205
break Orders
204206
}
205207
}
206208
case "http":
207209
if syncMode.Http && syncMode.HttpUseFallback {
208-
t.l.Info().Msg("using HTTP fallback")
210+
log.Info().Msg("using HTTP fallback")
209211
now = t.queryAllHttpTime(defaultHTTPUrls)
210212
if now != nil {
211-
t.l.Info().Str("source", "HTTP fallback").Time("now", *now).Msg("time obtained")
212213
break Orders
213214
}
214215
}
215216
default:
216-
t.l.Warn().Str("mode", mode).Msg("unknown time sync mode, skipping")
217+
log.Warn().Msg("unknown time sync mode, skipping")
217218
}
218219
}
219220

@@ -226,6 +227,8 @@ Orders:
226227
now = &newNow
227228
}
228229

230+
log.Info().Time("now", *now).Msg("time obtained")
231+
229232
err := t.setSystemTime(*now)
230233
if err != nil {
231234
return fmt.Errorf("failed to set system time: %w", err)

main.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,16 +96,25 @@ func Main() {
9696
if !config.AutoUpdateEnabled {
9797
return
9898
}
99+
100+
if isTimeSyncNeeded() || !timeSync.IsSyncSuccess() {
101+
logger.Debug().Msg("system time is not synced, will retry in 30 seconds")
102+
time.Sleep(30 * time.Second)
103+
continue
104+
}
105+
99106
if currentSession != nil {
100107
logger.Debug().Msg("skipping update since a session is active")
101108
time.Sleep(1 * time.Minute)
102109
continue
103110
}
111+
104112
includePreRelease := config.IncludePreRelease
105113
err = TryUpdate(context.Background(), GetDeviceID(), includePreRelease)
106114
if err != nil {
107115
logger.Warn().Err(err).Msg("failed to auto update")
108116
}
117+
109118
time.Sleep(1 * time.Hour)
110119
}
111120
}()

network.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var (
1515
networkState *network.NetworkInterfaceState
1616
)
1717

18-
func networkStateChanged() {
18+
func networkStateChanged(isOnline bool) {
1919
// do not block the main thread
2020
go waitCtrlAndRequestDisplayUpdate(true)
2121

@@ -37,6 +37,13 @@ func networkStateChanged() {
3737
networkState.GetFQDN(),
3838
}, true)
3939
}
40+
41+
// if the network is now online, trigger an NTP sync if still needed
42+
if isOnline && timeSync != nil && (isTimeSyncNeeded() || !timeSync.IsSyncSuccess()) {
43+
if err := timeSync.Sync(); err != nil {
44+
logger.Warn().Str("error", err.Error()).Msg("unable to sync time on network state change")
45+
}
46+
}
4047
}
4148

4249
func initNetwork() error {
@@ -48,13 +55,13 @@ func initNetwork() error {
4855
NetworkConfig: config.NetworkConfig,
4956
Logger: networkLogger,
5057
OnStateChange: func(state *network.NetworkInterfaceState) {
51-
networkStateChanged()
58+
networkStateChanged(state.IsOnline())
5259
},
5360
OnInitialCheck: func(state *network.NetworkInterfaceState) {
54-
networkStateChanged()
61+
networkStateChanged(state.IsOnline())
5562
},
56-
OnDhcpLeaseChange: func(lease *udhcpc.Lease) {
57-
networkStateChanged()
63+
OnDhcpLeaseChange: func(lease *udhcpc.Lease, state *network.NetworkInterfaceState) {
64+
networkStateChanged(state.IsOnline())
5865

5966
if currentSession == nil {
6067
return
@@ -64,7 +71,15 @@ func initNetwork() error {
6471
},
6572
OnConfigChange: func(networkConfig *network.NetworkConfig) {
6673
config.NetworkConfig = networkConfig
67-
networkStateChanged()
74+
networkStateChanged(false)
75+
76+
if mDNS != nil {
77+
_ = mDNS.SetListenOptions(networkConfig.GetMDNSMode())
78+
_ = mDNS.SetLocalNames([]string{
79+
networkState.GetHostname(),
80+
networkState.GetFQDN(),
81+
}, true)
82+
}
6883
},
6984
})
7085

0 commit comments

Comments
 (0)