|
|
@@ -2,6 +2,7 @@ package netmgrd
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
+ "math"
|
|
|
"os/exec"
|
|
|
"sync"
|
|
|
"time"
|
|
|
@@ -16,9 +17,9 @@ var servers = []string{
|
|
|
}
|
|
|
|
|
|
type ntpResult struct {
|
|
|
- t time.Time
|
|
|
- stratum uint8
|
|
|
- err error
|
|
|
+ t time.Time
|
|
|
+ d time.Duration
|
|
|
+ err error
|
|
|
}
|
|
|
|
|
|
func SyncNTPTime() error {
|
|
|
@@ -40,12 +41,21 @@ func getAccurateTime(servers []string, timeout time.Duration) (time.Time, error)
|
|
|
for _, s := range servers {
|
|
|
go func(s string) {
|
|
|
defer wg.Done()
|
|
|
+
|
|
|
resp, err := ntp.QueryWithOptions(s, ntp.QueryOptions{Timeout: timeout})
|
|
|
- if err != nil || resp.Stratum == 0 || resp.Stratum > 5 || resp.Time.IsZero() {
|
|
|
- ch <- ntpResult{err: err} // "resp.Stratum"为0(无效服务器)或大于5(精度较低)
|
|
|
+ if err != nil {
|
|
|
+ ch <- ntpResult{err: err}
|
|
|
return
|
|
|
}
|
|
|
- ch <- ntpResult{t: resp.Time, stratum: resp.Stratum}
|
|
|
+
|
|
|
+ if resp.Stratum == 0 || resp.Time.IsZero() {
|
|
|
+ ch <- ntpResult{err: fmt.Errorf("invalid ntp response")}
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ t := resp.Time.Add(resp.RTT / 2)
|
|
|
+ d := resp.RootDistance // 最大可能偏差
|
|
|
+ ch <- ntpResult{t: t, d: d, err: nil}
|
|
|
}(s)
|
|
|
}
|
|
|
|
|
|
@@ -54,34 +64,25 @@ func getAccurateTime(servers []string, timeout time.Duration) (time.Time, error)
|
|
|
close(ch)
|
|
|
}()
|
|
|
|
|
|
- var results []ntpResult
|
|
|
+ var bestTime time.Time
|
|
|
+ var bestDist time.Duration = math.MaxInt64
|
|
|
+
|
|
|
for r := range ch {
|
|
|
- if r.err == nil {
|
|
|
- results = append(results, r)
|
|
|
+ if r.err != nil {
|
|
|
+ continue
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- if len(results) == 0 {
|
|
|
- return time.Time{}, fmt.Errorf("所有NTP服务器请求失败或无有效时间")
|
|
|
- }
|
|
|
-
|
|
|
- // 找最低 Stratum
|
|
|
- minStratum := uint8(255)
|
|
|
- for _, r := range results {
|
|
|
- if r.stratum < minStratum {
|
|
|
- minStratum = r.stratum
|
|
|
+ if r.d < bestDist {
|
|
|
+ bestDist = r.d
|
|
|
+ bestTime = r.t
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 最低 Stratum 的时间
|
|
|
- var bestTimes []time.Time
|
|
|
- for _, r := range results {
|
|
|
- if r.stratum == minStratum {
|
|
|
- bestTimes = append(bestTimes, r.t)
|
|
|
- }
|
|
|
+ if bestTime.IsZero() {
|
|
|
+ return time.Time{}, fmt.Errorf("no valid ntp response")
|
|
|
}
|
|
|
|
|
|
- return bestTimes[0], nil
|
|
|
+ return bestTime, nil
|
|
|
}
|
|
|
|
|
|
var setTimeMu sync.Mutex // 保证调用 SetSystemTime() 函数的线程安全
|