diff options
Diffstat (limited to 'net/currenttime')
| -rw-r--r-- | net/currenttime/currenttime.go | 42 | ||||
| -rw-r--r-- | net/currenttime/currenttime_test.go | 14 | ||||
| -rw-r--r-- | net/currenttime/mintime.txt | 1 | ||||
| -rw-r--r-- | net/currenttime/update-current-time.go | 20 |
4 files changed, 77 insertions, 0 deletions
diff --git a/net/currenttime/currenttime.go b/net/currenttime/currenttime.go new file mode 100644 index 000000000..7ef2a1c56 --- /dev/null +++ b/net/currenttime/currenttime.go @@ -0,0 +1,42 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +// Package currenttime provides a fallback "current time" that can be used as +// the minimum possible time for things like TLS certificate verification. +// +// This ensures that if a Tailscale client's clock is wrong, it can still +// verify TLS certificates, assuming that the server certificate hasn't already +// expired from the point of view of the minimum time. +// +// In the future, we may want to consider caching the last known current time +// on-disk to improve the accuracy of this fallback. +package currenttime + +import ( + _ "embed" + "strconv" + "time" +) + +//go:embed mintime.txt +var minTimeUnixMs string + +var minCurrentTime time.Time + +func init() { + ms, err := strconv.ParseInt(minTimeUnixMs, 10, 64) + if err != nil { + panic(err) + } + minCurrentTime = time.UnixMilli(int64(ms)) +} + +// Now returns the current time as per [time.Now], except that if it is before +// the baked-in "minimum current time", that value will be returned instead. +func Now() time.Time { + now := time.Now() + if now.Before(minCurrentTime) { + return minCurrentTime + } + return now +} diff --git a/net/currenttime/currenttime_test.go b/net/currenttime/currenttime_test.go new file mode 100644 index 000000000..958a8436e --- /dev/null +++ b/net/currenttime/currenttime_test.go @@ -0,0 +1,14 @@ +package currenttime + +import ( + "testing" + "time" +) + +func TestMinTime(t *testing.T) { + // The baked-in time should always be before the current time. + now := time.Now() + if !minCurrentTime.Before(now) { + t.Fatalf("minCurrentTime is not before the current time: %v >= %v", minCurrentTime, now) + } +} diff --git a/net/currenttime/mintime.txt b/net/currenttime/mintime.txt new file mode 100644 index 000000000..5da66af78 --- /dev/null +++ b/net/currenttime/mintime.txt @@ -0,0 +1 @@ +1741638824797
\ No newline at end of file diff --git a/net/currenttime/update-current-time.go b/net/currenttime/update-current-time.go new file mode 100644 index 000000000..717a984ce --- /dev/null +++ b/net/currenttime/update-current-time.go @@ -0,0 +1,20 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +//go:build ignore + +package main + +import ( + "fmt" + "log" + "os" + "time" +) + +func main() { + contents := fmt.Sprintf(`%d`, time.Now().UnixMilli()) + if err := os.WriteFile("mintime.txt", []byte(contents), 0644); err != nil { + log.Fatal(err) + } +} |
