Toots for danderson@hachyderm.io account

Written by Dave Anderson on 2025-02-02 at 02:28

I ended up writing about my small descent into madness yesterday trying to understand why wireguard generates timestamps the way it does, and stumbling on a whole can of timekeeping worms: https://blog.dave.tf/post/tai64-is-not-tai/

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-02-02 at 01:49

Random TIL: the press headline is "The 27th meeting of the BIPM resolved to discontinue leap seconds by 2035", but the actual resolution doesn't say that.

What it says specifically is that BIPM will, by 2035, vote to increase the allowed offset between UT1 and UTC. Currently UTC is defined as remaining within 0.9s of UT1, with leap seconds inserted or removed as needed to stay within that delta.

The resolution that was passed is that the CIPM propose a new maximum value for the UT1-UTC delta, with the only established constraint so far being that the new value should make leap seconds unnecessary for at least a century.

So, leap seconds are staying, sort of. We're just going to relax the rule that currently triggers their use, in such a way that nobody currently alive will ever have to deal with leap seconds again. And then revisit once the committee is composed entirely of people who've never experienced a leap second, and will presumably go "that's stupid why would we do that" and actually delete them for good.

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-02-01 at 06:37

Zark help me, I'm considering writing a Forth.

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-02-01 at 03:23

Anyway, all this to say that libtai computes TAI64 timestamps incorrectly, and as a consequence so does wireguard. It doesn't actually matter in any way because all the implementations compute the wrong result in the same way, and thus agree with each other when computing relative durations, which is what they actually care about. But also, aaaaaaaaaaa why does the standard that attempts to use TAI to correctly assign predictable, clean timestamps to events get the timestamps wrong aaaaaaaaaaa

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-02-01 at 03:19

And in all this it's of course very confusing because leap seconds don't stop the passage of time over here in consensus reality, so surely this is meaningless and time counts up at one second per second all the time?

The key is that there's a difference between time elapsing, which it continues to do at one second per second all the time (let's not involve relativity please, my head hurts enough as it is), and the timestamps you strike according to a particular time standard.

If you strike a timestamp in UTC and TAI, wait 60 pulses of a 1 pulse/second atomic clock, and strike another pair of timestamps, they will both agree that 60 seconds have elapsed. What they won't agree on is what those instants in time are called. The TAI reference might say the start/end timestamp are 00:00:00 to 00:01:00, whereas the UTC reference might call those same instants in time 00:00:00 and 00:00:60, because leap second. Both time standards contain a timestamp 00:01:00, but they describe instants in time that are 1s apart.

When an API says it's returning the number of seconds elapsed since 1970-01-01 00:00:00 UTC, it could be saying two things: "an atomic clock that beeps once per second has beeped N times since 1970-01-01 00:00:00 UTC" (which would be the number of elapsed TAI seconds), or it could be saying "if you start at 1970-01-01 00:00:00 in the UTC time scale, and you increment the timestamp by 1 second N times, you will get the current time."

In the second definition, the key is that according to the UTC time scale, some minutes contain 61 seconds.

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-02-01 at 03:04

In conclusion, the notes of man 2 time that say it doesn't include leap seconds in order to align with posix, appears to be incorrect. What it means, I think, is that the kernel has no intrinsic awareness of leap seconds, and reports the number of seconds since epoch in a way that increments by 1 per second, where second is defined as "whatever my hardware timer and PLL logic say it is".

Which, in the absence of userspace clock discipline from NTP, is going to be very approximately the number of elapsed TAI seconds since the UTC epoch timestamp, with some random amount of leap seconds thrown in based on whoever manually set system time at some point.

In the presence of userspace discipline (e.g. NTP), the clock will be ticking in harmony with UTC/TAI's metronome, and will incorporate all UTC leap seconds known to userspace (which depends on tzdb freshness), and will also know the offset to TAI, so can give you either UTC or TAI timestamps depending on your preferences.

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-02-01 at 02:59

And indeed, using a tweaked version of the sample program graciously provided in man clock_settime, on my Linux system with NTP synchronization, I get:

time(NULL): 1738378600.???

CLOCK_REALTIME: 1738378600.580 (20120 days + 2h 56m 40s)

CLOCK_TAI: 1738378637.580 (20120 days + 2h 57m 17s)

time(NULL) agrees with CLOCK_REALTIME, which is exactly 37 seconds behind CLOCK_TAI. Therefore, it is indeed providing the number of seconds elapsed between the current instant's UTC timestamp, and the epoch timestamp 1970-01-01 00:00:00 UTC - including leap seconds.

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-02-01 at 02:50

Okay. Digging through Go's standard library implementation and the syscall surface, I believe the truth is:

Linux's CLOCK_REALTIME counts time as the number of UTC seconds since 1970-01-01 00:00:00 UTC, including leap seconds.

The kernel itself has no awareness of leap seconds, and relies on external synchronization (e.g. NTP) to adjust CLOCK_REALTIME when a leap second happens. As well as adjust its ticking rate to beat close to the metronome of UTC/TAI's clocks.

A userspace synchronizer such as ntpd can also provide the kernel with a TAI offset, in which case CLOCK_TAI will give you TAI time, with none of the leap seconds.

It's not clear to me that any of these return "TAI seconds since UTC Epoch" any more, now that NTP is more or less universal and dragging CLOCK_REALTIME along with UTC. But if the kernel is being fed the TAI offset, it could still comply with posix, by returning CLOCK_TAI+10 whenever it needs a "true" Unix timestamp. I think?

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-02-01 at 02:36

// By comparison, it's reasonable to mishandle some times in

// the year -292277022399.

Ah, I see the poor sod who implemented Go's time package is many years ahead of me in this particular abyss gazing exercise.

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-02-01 at 02:20

Or, I suppose, that the kernel only ever gets handed Unix "TAI since UTC Epoch" values, and then libc and all the other userspace friends grab tzdb (does tzdb carry leap second data? I assume so) and adjust things properly when formatting anything other than unix timestamps?

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-02-01 at 02:18

My only hope at this point is that NTP synchronization actually feeds the kernel both UTC timestamps and a correction factor back to Unix time, such that time(NULL) does in fact return "TAI seconds since the epoch instant", but other APIs let you have UTC time. But at this point I'm not sure I want to know.

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-02-01 at 02:09

Meanwhile, GPS is off in the corner, sniffing the marker pens, offset from TAI by 19 seconds. Because GPS time began on 6 January 1980, and on that day the UTC-TAI offset was 19 seconds.

Let's just forget the whole thing and go back to binary time: the two times are "dark outside" and "not dark outside", as defined by whether you can see the lion about to leap out from the bushes and eat you.

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-02-01 at 02:05

So, if my linux computer is synchronized to UTC using NTP, and I call time(NULL), and I add the number I get back to 1970-01-01 00:00:00 UTC, do I get a time that agrees with the UTC instant at which I called time(NULL), or do I get a timestamp that's offset by 27 seconds, that being the current UTC-TAI+10 offset?

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-02-01 at 02:03

It's actually sort of incredible, in that Unix time defines itself by reference to a UTC instant, but in ignoring leap seconds ends up counting more like TAI, except offset by 10 seconds because that was the UTC-TAI offset on 1970-01-01 00:00:00 UTC.

Oh and let's not forget that with most computers running NTP time synchronization now, the absolute timestamps you strike by asking the kernel most likely do account for leap seconds and are UTC, because that's what NTP synchronizes to unless you're a weirdo with a TAI fetish.

In conclusion, it is impossible to know the time by asking posix operating systems and it is a sin to ask.

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-02-01 at 01:58

Once again I was just minding my own business writing code, then I regained consciousness and was ranting about time standards, and doing conversion math between UT1, UTC, TAI, and losing my mind as I remember that the posix time() syscall states that it returns the number of seconds since 1970-01-01 00:00:00 UTC, but then in supplemental notes defines "the number of seconds since that instant" to not be, you know, the number of seconds elapsed since that instant, but merely an approximation of the number of seconds, which ignores leap seconds and therefore IS NOT UTC GOD FUCKING DAMNIT

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-01-31 at 19:54

I'd never looked in detail at wireguard's handshake algorithm. Today I finally had reason to, and TIL it always executes Noise IKpsk2, even when you don't provide a pre-shared key. If you don't provide one, the handshake executes with an all-zeros PSK.

I guess that makes sense, but for some reason I'd always assumed that it did plain Noise IK if you didn't configure a PSK. There's no issue with protocol matching, since wg is silent on other misconfigurations as well, and you could save a tiny amount of crypto operations by skipping the psk steps (a couple KDF runs and hashes). I presume it was deemed not a sufficient savings to justify having two distinct implementations of the handshake. Which, fair enough.

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-01-30 at 18:55

"Downloading the Fuchsia source code (which is about 2GB) can take a while"

I'm not surprised, 2GB takes a long time to download when it's in fact 35GB. Some documentation may be out of date I guess.

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-01-30 at 06:07

Again if this sounds like I'm making fun of rust and its opsem efforts, I'm really not. I'm glad they're doing the thing, and I'm amazed that we seemingly got this far on what seems like quite shaky ground.

But otoh when I come across a bug that starts with "why is const?" followed by an long intricate discussion that loses me in the first paragraph, I can't help but feel like I'm going mad.

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-01-30 at 06:03

"You don't understand! We can use the argent energy to stabilize the unsoundness! Without it, the global allocator is an unstable singularity!"

=> More informations about this toot | View the thread

Written by Dave Anderson on 2025-01-30 at 06:02

My new canon for Doom is that the future facility on Mars which opens a portal to hell turns out to be a miri extension that got out of hand.

=> More informations about this toot | View the thread

=> This profile with reblog | Go to danderson@hachyderm.io account

Proxy Information
Original URL
gemini://mastogem.picasoft.net/profile/109406782086158217
Status Code
Success (20)
Meta
text/gemini
Capsule Response Time
425.445026 milliseconds
Gemini-to-HTML Time
10.195862 milliseconds

This content has been proxied by September (3851b).