Recent Articles

Portable Sockets: Basics

In the modern world, people tend to use massive frameworks to accomplish simple tasks. Nothing quite like swatting a fly with a nuclear missile when you load up 100 megs of runtime just to execute ping and post the result to a database. But sometimes, when you’re writing a utility, you want it to be quick and lightweight. And if you’re going through the effort, you might as well see about making it portable.

Every extent Unix system uses BSD sockets for their networking layer, which traces back to 1983 and the release of 4.2BSD. In this model, network connections (“sockets”) are full fledged kernel objects that built on top of the existing Unix API (e.g. read, write, and close). Additional system calls were introduced both to create new sockets (e.g. socket) as well as provide networking-related operations (e.g. connect, listen, and accept).

By comparison, the original version of WinSock was a completely user space affair with its own API, loosely modeled on BSD sockets, but distinct from the system’s native interface. As the interface transitioned into the 32-Bit era with WinSock 2, it began to integrate more closely into the Win32 API. While Microsoft has written some material on porting Unix applications to WinSock, it leaves unanswered the question as to how to portably target both platforms.

Read More

Inline Functions in C and C++

Inline functions are a notable feature of both C and C++. By exposing the source file to the implementation of a function, they allow a variety of optimization techniques that wouldn’t be possible if it had to call out to a subroutine in a different file (at least without link-time optimization).

However, despite the common syntax, the C and C++ languages implement them in very different ways. While C++ takes a “user friendly” approach and automatically manages the manipulation of multiple implementations, C requires a more manual approach. As a result, inline functions are less common in C and mixed language code, generally using the nuclear option of declaring them static.

/* test.h */
inline int test1(void) {
  return 12;
}

/* test.c or test.cpp */
int test2(void) {
  return test1();
}

Sometimes, the easiest way to understand a rule is to see it in action. Let’s analyze how modern compilers deal with C and C++ inline functions in different situations.

Read More

FreeBSD Jail Startup Sequence

On my home server, I use FreeBSD. While FreeBSD beat Linux to the containers by nearly a decade (comparing jails to cgroups), I have to acknowledge that cgroups are the superior design. Whereas jails are a bunch of hacks piled on top of chroot, cgroups are a much cleaner abstraction of the kernel’s namespaces. But even beyond the elegance of the design, software like Docker makes it much easier to run your tools in containers, even if the offloading of sysadmin responsibilities it encourages triggers my OCD.

One of the things Docker does differently than most people’s usage of jails (at least from my limited understanding) is that a docker instance is ephemeral. The last time I touched iocage (years ago, granted), it was still focused on modeling jails like pets, not cattle. So I wanted my jails to go through the closest analog I could to Docker without porting over a massive ecosystem. That means if I’m going to write my own scripts, I need to understand how the FreeBSD jail system is put together.

Read More

wsgiref and Unix Domain Sockets

Recently, I needed to hack together a quick server-side application for a test page. When it comes to quick and dirty, most people turn to Python. While Python is hardly my favorite language, it is certainly suited for the task.

One of my requirements was that I wanted to minimize the number of dependencies. Installing Python is bad enough (my nginx container is extremely bare bones), but installing a massive framework for what was effectively a wrapper around a system command would make things even worse. So I decided to make due with wsgiref.simple_server that ships with CPython.

Unfortunately, when it came time to installing the script on the server, I discovered that simple_server only supports IPv4 and that is baked in. For security purposes, I like to use unix domain sockets whenever possible. It guarantees the endpoint can only be access from the local host and I can even configure permissions based on the user. Fortunately, it isn’t that hard to modify simple_server to support other protocols.

Read More

FreeBSD Encrypted ZFS Root on EFI

On my home server, I use FreeBSD. While the BSD’s have been falling behind Linux in the past decade, they still appeal to many people and even have a few tricks left in them. Most notably, as Linux has been struggling with next generation file systems for a few years now, FreeBSD has supported ZFS for over a decade.

While modern Linux distros become ever-more complex interplays of components, the BSD’s have remained relatively simple. Custom installation (by hand or script) is trivial when the system is distributed as a tarball or two versus a constellation of packages numbering in the thousands. Just boot into the live CD, format the file systems, unpack the tarballs, install the boot loader, and reboot into your new system.

While a custom installation allows you to fulfill your OCD tendencies, it requires you to have a strong understanding of how the system is constructed. Unfortunately, FreeBSD’s documentation has not been keeping up with the evolution with the system’s capabilities. For example, the page on efi(8) is extremely short and does not address modern concerns like ZFS and full disk encryption. In fact, much of the limited information on that page is downright misleading.

Read More

Subscribe via Atom or RSS