

dust blanket
Me: hmm, that’s an odd way to describe a bit of dust
[looks closely at photo]
Me: oh dear gawd!


dust blanket
Me: hmm, that’s an odd way to describe a bit of dust
[looks closely at photo]
Me: oh dear gawd!


In the end, programming is commanding a computer system to do your bidding. If your goal is to make electronic metal music, or complex 3d designs, simulate fluid dynamics, or solve for wheel settings on the Enigma machine, those are all programming tasks. Some may involve long runtimes, but the programming is giving the instructions to execute.
Even formulas in Excel are programming. But make no mistake that programming and software engineering are very different tasks: the latter is about devising good designs that balance countervailing interests. Software engineers define the problem which programmers would command onto a computer to find a solution or produce a product.


It is time for all
computing professionalsbillionaires and corporations to accept responsibility forcomputing’shumanity’s current state
FTFY
In all seriousness, Vardi correctly identifies the problems with “move fast and break things” and “efficiency at the expense of resilience”. Yet then uses victim-blaming language that “we allowed” mega corporations to exist. Even if the “we” is read as “society at large”, it cannot be reconciled with the call-to-action, which unambiguously targets the individuals of the industry. Without effective organization, no amount of individualized action can overcome a structural problem. It’s unclear to me what his point is.


I didn’t watch the video – and YT isn’t letting me speed-read a transcript? – but generally speaking, if you have a need for memory that isn’t backed by the filesystem, and you’re writing in C, just use malloc. It’s designed for that purpose, although malloc might very well be calling to mmap to obtain an anonymous mapping under the hood. Even if you’re going to hold on to memory for the entire lifetime of a program, still use malloc in C.
If your application does need some filesystem backing, or if you’re allocating enough memory that hugepages might be reasonable, then that’s when you’d want to use mmap.


The CA cannot decypt: they don’t have the secret key which only the server has. When requesting a new certificate from the CA, the server generated a secret key (aka private key) and then generated a derived public key that goes into a Certificate Signing Request (CSR). The CSR is what the CA receives, not the secret key, and then the CA returns the certificate file to the server, which has been endorsed by the CA and thus trusted by the user base.
Phrased another way, a certificate is the instrument that confirms that a purported public key can in-fact be safely used, and that no MITM attack is happening (assuming you trust the CA that signed the cert). But once you’ve confirmed the public key, the rest of the cryptography is public key cryptography, meaning the secrecy of the secret key is the whole game.


I think Signal tries to be E2EE but has other problems, including that MLS (the E2EE mechanism) inherently requires a client app instead of being usable with just a browser.
I’m having trouble imagining what in Signal’s implementation of the Double Ratchet, or any part of RFC9420 Message Layer Security, would inherently require a client app. Perhaps you mean that there is no readily available browser-implemented API for carefully managing secrets? Even in that situation, all the libraries needed to implement the RFC can be compiled as WebAssembly or to JavaScript (with the assumption that the browser and OS are outside a malicious actor’s capabilities) and ran that way.
To be clear, I’m not suggesting Signal is perfect, and papers about problems found in Signal and other apps are readily found, like this one from last month. But with that said, it does appear that OP’s described use-case involving hundreds of users in group chats is very much not what Signal was designed for,.


IMO, Leetcode and other programming exercises are a simulacrum for assessing aptitude. The exact exercise is not the point – though many managers might think otherwise – but rather is the process: can a candidate methodically approach a challenge with sufficient rigor as becoming of an engineer?
I’ve written before about what I look for when conducting interviews, in the context of embedded software engineers. In that realm, I’m usually probing for prior experience with computer architecture in general, not necessarily in the particular framework that the job will deal in. I want to see transferrable skills, because it’s kinda rare to actually find perfect candidates that already meet our final requirements. So instead, I expect candidates to be quick studies, the sort of people that can draw analogies and get an approximate answer. Everything else can reasonably be looked up in man pages and web searches.
But this might just be specific to embedded, where we do actually care about the nitty gritty compiler and assembly details, when there’s only 512 KB of RAM. And to be clear, a candidate that knows bit tricks will likely do well, but if that’s the only tool in their toolbox and they don’t or can’t understand why writing maintainable, mostly-portable code is important in a medium sized organization, then that could be a problem. In this realm, programming exercises are still a view into a mindset. Other CS fields may vary.


This is not AI text and you’re the one who’s departed from the OP’s request:
I am standing up a wiki
The definition of a wiki is unambiguous:
A wiki (/ˈwɪki/ ⓘ WIK-ee) is a form of hypertext publication on the internet which is collaboratively edited and managed by its audience directly through a web browser.
The entire context of OP’s post is web, ie the Internet. We are not taking about physical book libraries. We aren’t discussing microfiche. The only relevant database type germane to OP is a relational database, as you readily noted:
If you do additional web application mumbo jumbo, you might need a relational database


The filesystem is a database as well.
Only in the most reductionist sense would this be true. In practice, a relational database (ie has a schema and querying language) is no replacement for a hierarchical filesystem, and vice versa.
A filesystem stores binary blobs of data, and its up to each file format to define the semantics of the data contained. A database is a data structure coupled with accessors to present and cross-reference structured data. Trying to do a LEFT-JOIN on three binary files is a category error. And storing a PNG in a MariaDB table would be a sort of malpractice.
A closer comparison would be an SQL database versus a data serialization format like YAML. Both have structure and have data that can be acted upon in specific ways. Arithmetic can be performed on numeric values, and strings can be concatenated together. But neither will let you concatenate numeric values, such as 2 + 2 = “22”. You need a programming language like PHP to perform such shenanigans.
In the context of serving web content, the filesystem is the domain of the OS, meaning it has been honed by decades of experience to make it as performant as possible, built into the kernel to utilizing whatever caching tricks that make sense, and this is available irrespective of the specific userspace stack (eg LAMP) that is running. However, no mainline OS has a relational database built into the kernel and is available for a web application to use. Database engineers go through great pains to optimize a system to run as a database server.
Phrased another way, there are no mainline OS’s that omit the filesystem. So removing the need for a relational database is removing an attack surface, removing a dependency, removing another thing that can break. The point of a database is to look up pieces of data. But if a web server can just serve up a whole HTML file that includes all the data needed, then the database can be omitted and performance will be higher as a result.
Can a filesystem be used in lieu of a database? Sure but there are many things which can be done but shouldn’t in all normal circumstances. That is the crux of engineering: to select the right tool for the job.


If scale is a concern, then you want to be reducing drag as much as possible. Database lookups and edits can get expensive, so maybe just avoid them outright: DokuWiki only requires a web server with PHP. It keeps content as plain files, making it easy to serve up and to back up.
But it’s often said that perfection is when nothing can be taken away, so what if we remove PHP as well? In this case, we need the content to already be rendered HTML. And we can do that, since there’s a body of site generation packages that build from Markdown files. I found this one while randomly searching: https://codeberg.org/milofultz/swiki
At this point, it’s just a plain web server that dishes out static HTML files. Such simplicity will withstand most AI scrapers, because the cost per request is now absurdly low. And caching a static site is not particularly difficult. Indeed, if the sum total of the wiki content is small enough, it might even fit into something like Codeberg Pages, which means we’ve eliminated even the web server (though this would depart from c/selfhosted).
What seems to be missing from that swiki package – but is entirely feasible – would be to have all content in Markdown files and live in a Git repo, and the Git history itself is used as the Wiki history. This means your pages would retain the classic wiki change log, so that it can all be generated from a Git repo that’s small enough to keep on a floppy disk.


This and the comment it replies to make the categorical error which is to assume that NAT exists as part-and-parcel to firewalling. This is not the case. Many American university and corporate networks do still adhere to the end-to-end principle by giving every device a public IP address. They can do this because they are among the few legacy entities that actually have enough for their needs, such as a Class A (aka /8) subnet on Legacy IP. At the same time, these entities employ firewalls that don’t allow unsolicited inbound traffic (and sometimes also block disallowed outbound traffic).
NAT is not a firewall, and the OP correctly points out that by using NAT or CGNAT, the end to end principle is demolished, with no way for the victims to recover. OP mentions “firewalls” exactly twice, to compare how they are not firewalls and are still necessary in spite of NAT. Nobody is credibly suggesting that everyone should switch to IPv6 without a firewall. Every single domestic router for the past two decades has included a firewall, and that would not change in an all IPv6 world.
I wish to reiterate an example I’ve used in the past, which is that the most famous address in the USA is 1600 Pennsylvania Ave, Washington DC. Anyone can send letters and parcels directly to this address as-written, with no need to rewrite the address to first arrive at the Secret Service. And yet, all such parcels and letters will be thoroughly scrutinized by the Secret Service anyway at an off-site facility, and some indeed will be let through to the occupants of the residence. NAT is address mutilation, and the United States Postal Service does not require nor allow that.


What are these “built in listeners” that you speak of, and which OS’s can I find this on?
Also TCP will work before UDP. For whatever reason firewalls and such do weird things with UDP traffic.
This doesn’t really explain why troubleshooting is more difficult, but rather that firewalls often cause trouble for UDP. My question was “why would diagnosing a UDP problem be harder than anything else?”, not “why is UDP more problematic?”. I’m fully aware that some firewalls are configured with absurd parameters, like blocking ICMP, QUIC, or even TLS in some bizarre situations. But my tools for debugging network troubles have always been the same: tcpdump for passive tracing, nc to coerce an active response, and icmp/icmp6 ping for basic connectivity and MTU verification.
Whether it’s UDP or anything other protocol, those tools have proven sufficient for me. Do you use something else?


I’ll add some color to this post.
The original FTP is, frankly, a monster of a protocol. Very useful, but an anomalous protocol that even without NAT breaking the end-to-end principle, it is unlikely to have survived modern corporate firewall rulesets in any case. The fact that FTP was even ported for TCP is its own historical quirk.
BTW, that is the term which this post is missing: the end-to-end principle is the design philosophy that the network itself should not have to perform work on payloads transmitted, except to carry it towards the destination. This also implies that no fields or bits should be modified in transit, once it leaves the sender; encap/decap restores the fields so that the receiver is none the wiser.
NAT breaks end-to-end in two respects: corruption of the original sender, and corruption of L4 port numbers. Note that Legacy IP also violated end-to-end, when packets are fragmented due to MTU issues. With IPv6, fragmentation by the network is disallowed outright, and the technical case for NAT is non-existent.
There’s something to be said about adopters of NAT, that they were facing a Hobson’s choice: use NAT so that they could connect early dial-up users to the emerging Internet, or reinvent the 20 year experiment of the Internet so that it could scale properly. In 1995, IPv6 did not exist so they made the only real choice available.
In the year 2026 though, that argument doesn’t hold water: it is a choice to continue to ignore the dual-stack and IPv6-only internet. There’s a quote that all sufficiently complex technical problems are in-fact political, and this is that: the modern case for Legacy IP and NAT is rooted in inertia, resource scarcity (eg hyperscale cloud companies buying up IP subnets), and recalcitrance by professionals that abdicate their responsibility to their clients to pursue the available technology.
There is no colorable technical rationale for why IPv6 best practices cannot be adopted today for most organizations, when all network hardware, all major consumer and enterprise OS’s, and all mobile phones support v6. Note that I said “best practices”, because a minority of orgs such as certain American ISPs have undertaken truly bonkers decisions that are putting us on track for the very same sins as Legacy IP.
The fact that some ISPs assign nothing but a single /128 via DHCP6 is absurd: this malpractice perpetuates the same problem as NAT44, except that there’s no good excuse for it. Even the most delusional of ISPs will never run out of /128 addresses in their assigned /32. Per best practice, even handing out /48’s to customers is not a problem either, because that’s 65536 customers and if that’s really a problem, just ask the RIR for another /32, which they can do as RIR dues-paying members. There is no practical limit, except that some people just cannot math properly to see that there’s no practical limit. When a technical solution to a technical problem fails because of innumeracy by those tasked with implementing it, then that’s so much worse than any 1990s workaround.
I’ve harped a lot about IPv6 because its strength today is that it’s technically competent, future-proofed, and most importantly, practitioners that saw the first travesty of NAT will not allow a redux to play out with IPv6. The technical reasons to deploy NAT66 are non-existent: it is always a workaround for political issues.
I can (just barely) accept NPTv6 as a like subnet-for-subnet mapping that does not harm L4, but that’s still glossing over a political issue. IPv6 gave network engineers real choices in numbers and administering their networks, and while some will squander it, I will be encouraging people to not let that happen.


Why would UDP be any more difficult than TCP (or anything else) for troubleshooting? If nothing else, it should be easier because there are no stateful connections and every packet is “fire and forget”. Now, as a tunneling technology, WG might be more difficult than a simple client/server socket-driven application, but that just means some routing tables need to be inspected and you have to understand IP subnets. In any case, you’d still want to obtain packet traces from both ends of the WG tunnel.


The thing is, if you don’t wish to port-forward on Legacy IP nor open firewall ports for IPv6, then the only other option is to reach out to some sort of relay server. But whether your own VPS fulfils that role or you use Tailscale’s DERP/TURN relays, the same class of latency and bandwidth issues will still erupt. So you’d still have to debug them, although you presumably would have better visibility into diagnosing issues with your VPS relay.
Generally speaking, if Tailscale isn’t working for you, then all other solutions will increase in complexity, not decrease.
Answering the ultimate question, I operate and secure my SSH server, with port 22 open only for IPv6 inbound. There’s no NAT, so I don’t have to deal with debugging odd port mangling. The SSH server only allows key auth, and all password attempts are logged and blocked, because there can’t be any legitimate traffic like that. On this SSH server would be my mounts for backups.


IIRC, the USA Social Security Administration’s website operates somewhat like this, because they seem to still do batch processing (a la mainframes) during the evening hours. As a result, they prevent people from logging in so that they don’t get interstitial data about their public pension.


Having conducted technical interviews after managers have screened the candidates’ resumes, I second this. Businesses absolutely look at example works, precisely because it’s what they care about: it doesn’t take a leap of the imagination that if someone has churned out excellent work for hire, that they can do it again once hired on.
It’s a bit harder for prospective employers to take someone at their word without works that they can point to, or can succinctly describe said works in sufficient detail.


I skimmed this article, but I’ll revisit it later because MPU protections have always intrigued me, in terms of being a much smaller subset of the protections afforded by an MMU. That said, for work projects, I’ve only ever been able to make use of MPU regions for coarse-grain protection (eg prevent the DMA-dedicated regions from being accessible by everything) and not for per-task protection. So I’m always interested in ways that more isolation can be applied, precisely because it keeps code honest, which isn’t a bad thing. It’s no different than having software asserts.


This looks amazing. That said, you may want to have a look at rules 7 and 8 for this community.
For other folks reading, be mindful that not all PC fans can efficiently draw airflow through a filter. The key word is “static pressure”, which refers to how much force can be exerted on a fully-blocked opening, which would then produce airflow through the parts that are less blocked. The simplest PC fans basically have zero static pressure, and so they’ll just spin uselessly when covered by an HVAC filter.
As an aside, dust and lint in PCs can be reduced by limiting dust and lint in the environment: replacing your home HVAC filter, not wearing shoes indoors, electrostatic fans, and using mechanical ventilation rather than opening the window are effective ways to keep detritus away from your machine in the first place.