Thomas Habets writes about systems programming, Go, C, Rust, Linux networking, and security tooling like SSH and GPG with Yubikeys.
Commenters cite his posts on Go's rough edges and undefined behavior in C, and his static linking article, in technical debates.
13 years ago I wrote a nice reference implementation for BGP "client" use - I just treated it as an API onto Cisco routers: https://github.com/BytemarkHosting/bgpfeeder is 1300 lines of Ruby, one file, no dependencies, and quite verbose.
At the time I was running a hosting company & wanted to feed updates to our IP lists from a web-based database into our routers (e.g. a customer wants a new IP to their servers, or moves their VPS images between physical hosts). But I couldn't understand how to get tight control of quagga, or the Ciscos and wondered how how to speak it directly?
It took about a week poring over the RFCs and the Net::BGP Perl module, but I can go back to it now for some useful revision. It brought a lot of disparate BGP knowledge together in one place, and re-expressed it in a language I still know. So if you know Ruby and are curious about BGP it might help you see what you can do with it.
Though if you want to use BGP to control your network devices today, you'd use https://github.com/Exa-Networks/exabgp instead. It can pull every trick you could possibly want with BGP - e.g. DDoS mitigation, anycast, and generally letting you mess with BGP via JSON. There are lots of extensions to BGP, and I only cared about the ones to send v4 & v6 routes around. Also I only wanted to write one file :)
PS, there is one horror in BGP implementation and that is TCP-MD5. i.e. to authenticate to a peer, you sign every packet of your TCP connection with a little…
> I disagree. Bash basically cannot be used correctly. It's like gets() in C; a knife with a blade but no handle. Unsafe at any speed.
> C++ can be used correctly. It's easier since C++11, with smart pointers and stuff. I'm not going to argue that writing solid C++ is easy, but it IS possible.
It seems this conflates two different aspects of programming languages - complexity and (memory) safety.
The analogy with Bash was in relation to the language complexity. By reducing the language features to a restricted, well-known (by the given team) scope, it's possible to use the language effectively. A very good example of this is the Doom 3 source code.
In relation to memory safety, Google hasn't been able to develop a safe enough Bluetooth stack, which has been a dumpster fire. Due to the small support windows of Android, as of today, a huge amount of devices with older Android versions are either in the garbage, or are extremely unsafe. If Google, with their engineering practices, can't develop a safe Bluetooth stack in an unsafe language, realistically, nobody can.
> https://blog.habets.se/2021/06/The-uselessness-of-bash.html
The topic in the post is very interesting (pipes error handling are no doubt a rough area of Bash), but the post takes the choice of being a rant rather than an informative research. The central thesis that "functionality of language X is broken in a 1-line program, but it works in a 83-lines program in language Y" doesn't have any meaningful…
The question is, what is simplicity?
Go tries to hide the issues, until a data loss happens because it has had trouble dealing with non-UTF8 filenames and Strings are by convention UTF8 but not truly and some functions expect UTF8 while others can work with any collection of bytes.
https://blog.habets.se/2025/07/Go-is-still-not-good.html
Or the Go time library which is a monster of special cases after they realized they needed monotonic clocks [1] but had to squeeze it into the existing API.
https://pkg.go.dev/time
Rust is on the other end of the spectrum. Explicit over implicit, but you can implicitly assume stuff works by panicking on these unexpected errors. Making the problem easy to fix if you stumble upon it after years of added cruft and changing requirements.
[1]: https://github.com/golang/go/issues/12914
I'd say yes we are ready. gettimeofday() should never be used to measure time[1], but at least with a negative leap second it's monotonic.
We'll just get some poorly coded stuff claim that an operation took 1100ms instead of 100ms. Not great, but not -900ms.
Well, I say that, but per my link here F5 load balancers at least used to keep track of TCP connections using gettimeofday. And it's annoying that libpcap delivers metadata in wallclock time.
[1] https://blog.habets.se/2010/09/gettimeofday-should-never-be-used-to-measure-time.html
Does using the Yubikey in this manner protect your keys even if your machine has malware on it? I read through this tutorial [1], and they say you need read/write access to the device, so it seems to me like malware could access your keys while the smartcard is plugged in. If this is the case, I'm not sure how this setup is any more secure than simply keeping your keys on a USB flash drive and plugging it in whenever you need to use ssh.
[1] https://blog.habets.se/2013/02/GPG-and-SSH-with-Yubikey-NEO
Will this be virtualisable so multiple VMs sharing a host will see separate, independent devices?
On desktops and laptops, will this device have a hardwired user-presence sensor, like Yubikeys do?
Would this device be performance-oriented enough to, for example, terminate SSL? I gather TPMs can, but only unhelpfully slowly [1]
Would it be performance-oriented enough to perform disk encryption? What about memory encryption?
[1] https://blog.habets.se/2012/02/Benchmarking-TPM-backend-SSL.html