Skip to content

Commit 873fc91

Browse files
committed
Add support for using DHCP-provided NTP server
1 parent 087487f commit 873fc91

File tree

3 files changed

+73
-9
lines changed

3 files changed

+73
-9
lines changed

internal/network/netif.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type NetworkInterfaceState struct {
2121
ipv6Addr *net.IP
2222
ipv6Addresses []IPv6Address
2323
ipv6LinkLocal *net.IP
24+
ntpAddresses []*net.IP
2425
macAddr *net.HardwareAddr
2526

2627
l *zerolog.Logger
@@ -76,6 +77,7 @@ func NewNetworkInterfaceState(opts *NetworkInterfaceOptions) (*NetworkInterfaceS
7677
onInitialCheck: opts.OnInitialCheck,
7778
cbConfigChange: opts.OnConfigChange,
7879
config: opts.NetworkConfig,
80+
ntpAddresses: make([]*net.IP, 0),
7981
}
8082

8183
// create the dhcp client
@@ -89,7 +91,7 @@ func NewNetworkInterfaceState(opts *NetworkInterfaceOptions) (*NetworkInterfaceS
8991
opts.Logger.Error().Err(err).Msg("failed to update network state")
9092
return
9193
}
92-
94+
_ = s.updateNtpServersFromLease(lease)
9395
_ = s.setHostnameIfNotSame()
9496

9597
opts.OnDhcpLeaseChange(lease)
@@ -135,6 +137,27 @@ func (s *NetworkInterfaceState) IPv6String() string {
135137
return s.ipv6Addr.String()
136138
}
137139

140+
func (s *NetworkInterfaceState) NtpAddresses() []*net.IP {
141+
return s.ntpAddresses
142+
}
143+
144+
func (s *NetworkInterfaceState) NtpAddressesString() []string {
145+
ntpServers := []string{}
146+
147+
if s != nil {
148+
s.l.Debug().Any("s", s).Msg("getting NTP address strings")
149+
150+
if len(s.ntpAddresses) > 0 {
151+
for _, server := range s.ntpAddresses {
152+
s.l.Debug().IPAddr("server", *server).Msg("converting NTP address")
153+
ntpServers = append(ntpServers, server.String())
154+
}
155+
}
156+
}
157+
158+
return ntpServers
159+
}
160+
138161
func (s *NetworkInterfaceState) MAC() *net.HardwareAddr {
139162
return s.macAddr
140163
}
@@ -318,6 +341,25 @@ func (s *NetworkInterfaceState) update() (DhcpTargetState, error) {
318341
return dhcpTargetState, nil
319342
}
320343

344+
func (s *NetworkInterfaceState) updateNtpServersFromLease(lease *udhcpc.Lease) error {
345+
if lease != nil && len(lease.NTPServers) > 0 {
346+
s.l.Info().Msg("lease found, updating DHCP NTP addresses")
347+
s.ntpAddresses = make([]*net.IP, 0, len(lease.NTPServers))
348+
349+
for _, ntpServer := range lease.NTPServers {
350+
if ntpServer != nil {
351+
s.l.Info().IPAddr("ntp_server", ntpServer).Msg("NTP server found in lease")
352+
s.ntpAddresses = append(s.ntpAddresses, &ntpServer)
353+
}
354+
}
355+
} else {
356+
s.l.Info().Msg("no NTP servers found in lease")
357+
s.ntpAddresses = make([]*net.IP, 0, len(s.config.TimeSyncNTPServers))
358+
}
359+
360+
return nil
361+
}
362+
321363
func (s *NetworkInterfaceState) CheckAndUpdateDhcp() error {
322364
dhcpTargetState, err := s.update()
323365
if err != nil {

internal/timesync/timesync.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ type TimeSync struct {
2828
syncLock *sync.Mutex
2929
l *zerolog.Logger
3030

31-
networkConfig *network.NetworkConfig
31+
networkConfig *network.NetworkConfig
32+
dhcpNtpAddresses []string
3233

3334
rtcDevicePath string
3435
rtcDevice *os.File //nolint:unused
@@ -62,12 +63,13 @@ func NewTimeSync(opts *TimeSyncOptions) *TimeSync {
6263
}
6364

6465
t := &TimeSync{
65-
syncLock: &sync.Mutex{},
66-
l: opts.Logger,
67-
rtcDevicePath: rtcDevice,
68-
rtcLock: &sync.Mutex{},
69-
preCheckFunc: opts.PreCheckFunc,
70-
networkConfig: opts.NetworkConfig,
66+
syncLock: &sync.Mutex{},
67+
l: opts.Logger,
68+
dhcpNtpAddresses: []string{},
69+
rtcDevicePath: rtcDevice,
70+
rtcLock: &sync.Mutex{},
71+
preCheckFunc: opts.PreCheckFunc,
72+
networkConfig: opts.NetworkConfig,
7173
}
7274

7375
if t.rtcDevicePath != "" {
@@ -78,6 +80,10 @@ func NewTimeSync(opts *TimeSyncOptions) *TimeSync {
7880
return t
7981
}
8082

83+
func (t *TimeSync) SetDhcpNtpAddresses(addresses []string) {
84+
t.dhcpNtpAddresses = addresses
85+
}
86+
8187
func (t *TimeSync) getSyncMode() SyncMode {
8288
syncMode := SyncMode{
8389
Ntp: true,
@@ -170,7 +176,15 @@ Orders:
170176
break Orders
171177
}
172178
}
173-
case "ntp_fallback":
179+
case "ntp_dhcp":
180+
if syncMode.Ntp {
181+
t.l.Info().Msg("using NTP servers from DHCP")
182+
now, offset = t.queryNetworkTime(t.dhcpNtpAddresses)
183+
if now != nil {
184+
t.l.Info().Str("source", "NTP DHCP").Time("now", *now).Msg("time obtained")
185+
break Orders
186+
}
187+
}
174188
case "ntp":
175189
if syncMode.Ntp && syncMode.NtpUseFallback {
176190
t.l.Info().Msg("using NTP fallback")

network.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ func networkStateChanged() {
1919
// do not block the main thread
2020
go waitCtrlAndRequestDisplayUpdate(true)
2121

22+
if timeSync != nil {
23+
if networkState != nil {
24+
timeSync.SetDhcpNtpAddresses(networkState.NtpAddressesString())
25+
}
26+
27+
timeSync.Sync()
28+
}
29+
2230
// always restart mDNS when the network state changes
2331
if mDNS != nil {
2432
_ = mDNS.SetListenOptions(config.NetworkConfig.GetMDNSMode())

0 commit comments

Comments
 (0)