Elizafox's Ramblings

The blag/dumping ground of Elizabeth Ōkami

Once upon a time I built a weather station. I don't have any photos lying around, but I could ask Anna if she has any.

I named the project Weatherbox, after a song by Mission of Burma (see here).

By built, I don't mean I bought one. I mean I literally built it myself, from raw components.

I'll tell you how you can, too, along with some things I will do differently in the future.

Components

Full disclosure: I am an Amazon Associate and I may earn commission on these links; you won't be charged extra for this. I know it sounds scummy or that I'm selling out, but I need the money. Please consider using the links below to buy the materials in question!

Here are some of the things I used. I wouldn't necessarily use all these components now, but they worked at the time:

Electrical components

Mounting hardware

  • This mount, although I'd probably consider a different one, this one I know works
  • This junction box, I drilled some holes in the side and used some O-rings to keep water out
  • I modified this LaCrosse temperature sensor housing as a housing for the BME680 and such by sawing off the internal mount and enlarging the holes for wires; but there are better options
  • U-bolts I got from Lowe's, it isn't worth it to buy them online, I used them to mount the junction box to the pole
  • Hose clamps to attach the mount to my railing at my apartment, although you don't have to

Prototyping and assembly equipment

  • 22 AWG wire
  • If you don't have a soldering station, the X-Tronic 3020-XTS is good value for money, although I found the helping hands of questionable value, the rest is great
  • Jumper wire for prototyping
  • Decent breadboards; Elegoo's are okay
  • A long MicroUSB cable; I never got around to adding a solar panel, my apartment area was too shaded
  • Some 1% tolerance or better resistors, these “BOJACK” ones (whatever that means) are okay; 0.25 watt resistors are fine, although 0.5 watt is fine too, it doesn't really matter, we aren't putting that much current through them
  • Heat shrink, I used this and it was fine
  • A stripboard track cutter, similar to this although perhaps you may not want to get it off Amazon because there don't seem to be many and the one I could find had bad reviews; I don't remember where I got mine, it wasn't Amazon though
  • Some pin headers, any will do, for breakout boards that don't have them, although you can also just use wire
  • A lighter for the heat shrink

Miscellaneous components

Assembly

I didn't keep photos of the assembly process, though I wish I had. It took me a lot of trial and error to get it right and settle on a design I was happy with.

In the end, I settled on a design where my Arduino 33 IoT would connect to the network, and my Raspberry Pi Zero would poll it for data and upload it to my site.

Layout

The Arduino itself lived in the junction box. All the ports were on the bottom of the box, with grommets to prevent water ingress. I added some extra grommets to ensure at least some airflow.

I broke out the BME680 onto its own daughter board, and put it in the aforementioned LaCrosse housing. I found the junction box could get quite warm and would cause inaccurate readings, plus we want plenty of airflow anyway for the air quality measurement.

The UV sensor was covered in the aforementioned conformal coating and attached with epoxy to the top of the junction box. I just used some wires and wired it to the Arduino in the box. I added a drip loop to the wire to ensure it wouldn't cause issues.

For the anemometer and rain gauge, I used pull-up resistors (2K resistors worked best I found, but you could probably get away with a 5K or even 10K resistor) and a 2pF capacitor in series for filtering. I did most of my debouncing in software, however. I just hooked up the connectors to little pieces of stripboard I cut out for the purpose to mount the resistors and capacitors.

The wind vane was trickiest. Here is the datasheet. As the PDF says, “it has eight switches, each connected to a different resistor.” I used a 10K ohm resistor like it suggested to create a voltage divider, which I hooked up to the ADC on the Arduino. I ran a binary search to find the correct voltage value. I find that the “in-between” measurements are fiddly and only work in certain directions. One should expect to have 8 indicated positions total and no more, and anything else is a bonus. This is fine for a hobbyist project, but do keep that in mind. I would definitely experiment and see how your wind vane reacts. This is the point where good tolerance resistors are helpful.

Most of the discrete breakout board components speak I2C, so I just hooked them all up to the I2C line. You may want to add I2C buffers if you're getting lots of interference or too much capacitance. Something like this may help.

Prototyping

I cannot emphasise this enough, you must prototype, prototype, prototype. Do everything on breadboards before you put it on stripboard. They have their limitations, but they'll help you get a feel for how the components work. I found the fiddliest part was not the I2C bus, but the weather vane/anemometer/rain gauge. It took me ages to figure out I needed a pull-up on them, and even longer to debug the circuit for the wind vane.

Source

I have some code here that you can adapt to this project or just use. You'll want to swap out the Si1145 UV sensor code if you use the S12SD. It gives a simple analog reading, documented here.

What I'd do different

I did mention a few things I'd change, like swapping out the Si1145 for the S12SD and maybe a different mount.

I think a big change I'd make, perhaps the biggest of all, would be to swap out the anemometer, wind vane, and rain gauge, for discrete components that didn't all just come together in a kit. Something far more professional would be in order. This will require fabricating some mounts, but I think that's within my abilities. I plan to do that for the second iteration of this project.

I would definitely spend more time on the breadboard working things out than I would otherwise.

I found the WiFi fiddly and annoying. I would probably switch to LoRa communications instead of WiFi, this would also enable me to use the cheaper Arduino 33 BLE. I'd just have to get it working with the Pi Zero.

I had a lot of stuck I2C bus problems, likely due to capacitance issues. I would definitely use a buffer as aforementioned, and perhaps a simple transistor to fully shut down all devices on the bus and restart all devices.

In the future, I would like to make this solar powered. I'll need to find a cooling/heating solution for the battery, however, to keep it within temperature ranges (especially as the PNW gets hotter and with our sometimes cold winters).

Notes

I didn't need any 5V components for this project. 3.3V is increasingly the standard for breakouts and sensors. Not even the anemometer, wind vane, or rain gauge needed 5V. If you use an Arduino 33 Nano series board and want to use 5V components, you'll have to bridge the 5V connector to enable the 5V regulator. You'll likely want logic level converters to avoid damaging the Arduino, or voltage dividers, as it can't take more than 3.3V on its pins except ground.

— Elizabeth Ōkami (Elizafox) Fedi (elsewhere): @Elizafox@social.treehouse.systems Tip jar: PayPal || CashApp || LiberaPay

I noticed something peculiar whilst tinkering with my jail. The impact of this oversight is probably minimal to none (it certainly leads to nothing exploitable), but it's IMO a bug that should be fixed.

UPDATE: I have filed a bug

Note to CVE clout chasers

Before you go running out and getting a CVE:

Don't.

You will make a total ass of yourself, and I will point back to this blog post, and I will laugh at you.

Things this can do

  • Allow you to see how the jail is configured on the host to a very limited extent (at least the filesystem layout, in part)

Things this cannot do

  • Help you escape the jail
  • Help you obtain elevated privileges outside the jail
  • Help you obtain privileges inside the jail
  • Exploit the system in any way
  • Let you do anything that you couldn't do with a real kernel exploit, which you would probably need to successfully escape the jail

Background

Jails in FreeBSD are a container mechanism, albeit not quite as comprehensive as Linux namespace containers like LXC. They've been around about 23 years, being introduced in March 2000. I think it may be best to think of them more as a replacement for jailing things via chroot (long since known to be insecure, because chroot is not a security mechanism) that has sort of evolved into a container.

The problem

If you run procstat vm $PID in a jail:

root@z6a.info:/ # procstat vm 989
  PID              START                END PRT  RES PRES REF SHD FLAG  TP PATH
  989      0x20210af3000      0x20210af7000 r--    4   10  22   2 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/usr/sbin/rtsold
  989      0x20210af7000      0x20210afe000 r-x    7   10  22   2 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/usr/sbin/rtsold
  989      0x20210afe000      0x20210aff000 rw-    1    0   5   0 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/usr/sbin/rtsold
  989      0x20210aff000      0x20210b01000 rw-    2    0   1   0 C---- sw
  989      0x20a11ab8000      0x20a31a98000 ---    0    0   0   0 ----- gd
  989      0x20a31a98000      0x20a31ab8000 rw-    3    0   1   0 C--D- sw
  989      0x20a32148000      0x20a32169000 rw-    7    0   1   0 C---- sw
  989      0x20a3290c000      0x20a3290f000 r--    3    6  32  12 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libcasper.so.1
  989      0x20a3290f000      0x20a32912000 r-x    3    6  32  12 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libcasper.so.1
  989      0x20a32912000      0x20a32913000 r--    1    0   5   0 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libcasper.so.1
  989      0x20a32913000      0x20a32914000 rw-    1    0   5   0 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libcasper.so.1
  989      0x20a32914000      0x20a32915000 rw-    1    0   1   0 C---- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libcasper.so.1
  989      0x20a3335c000      0x20a33364000 r--    7   19  52  18 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libutil.so.9
  989      0x20a33364000      0x20a3336f000 r-x   11   19  52  18 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libutil.so.9
  989      0x20a3336f000      0x20a33370000 rw-    1    0   5   0 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libutil.so.9
  989      0x20a33370000      0x20a33371000 rw-    1    0   1   0 C---- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libutil.so.9
  989      0x20a33371000      0x20a33373000 rw-    0    0   0   0 ----- --
  989      0x20a33855000      0x20a33856000 r--    1    2  24   4 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/casper/libcap_syslog.so.1
  989      0x20a33856000      0x20a33858000 r-x    2    2  24   4 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/casper/libcap_syslog.so.1
  989      0x20a33858000      0x20a33859000 rw-    1    0   5   0 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/casper/libcap_syslog.so.1
  989      0x20a33859000      0x20a3385a000 rw-    1    0   1   0 C---- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/casper/libcap_syslog.so.1
  989      0x20a34523000      0x20a345a8000 r--   78  321  89  41 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libc.so.7
  989      0x20a345a8000      0x20a346f3000 r-x  219  321  89  41 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libc.so.7
  989      0x20a346f3000      0x20a346fc000 r--    9    0   5   0 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libc.so.7
  989      0x20a346fc000      0x20a346fd000 rw-    1    0   5   0 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libc.so.7
  989      0x20a346fd000      0x20a34704000 rw-    7    0   1   0 C---- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libc.so.7
  989      0x20a34704000      0x20a34926000 rw-    7    0   1   0 C---- sw
  989      0x20a355cd000      0x20a355d7000 r--    8   20  30  10 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libnv.so.0
  989      0x20a355d7000      0x20a355e4000 r-x   12   20  30  10 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libnv.so.0
  989      0x20a355e4000      0x20a355e5000 rw-    1    0   5   0 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libnv.so.0
  989      0x20a355e5000      0x20a355e7000 rw-    2    0   1   0 C---- vn /usr/jails/basejail/base_amd64_amd64_13.2/lib/libnv.so.0
  989      0x20a36200000      0x20a36400000 rw-    2    0   1   0 C---- sw
  989      0x20a366f9000      0x20a368f9000 rw-   18    0   1   0 C---- sw
  989      0x20a37800000      0x20a37c00000 rw-    1    1   1   0 C---- sw
  989      0x20a38947000      0x20a38948000 rw-    0    0   1   0 ----- sw
  989     0x31ae14de4000     0x31ae14deb000 r--    7   29  76  28 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/libexec/ld-elf.so.1
  989     0x31ae14deb000     0x31ae14e01000 r-x   22   29  76  28 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/libexec/ld-elf.so.1
  989     0x31ae14e01000     0x31ae14e02000 r--    1    0   5   0 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/libexec/ld-elf.so.1
  989     0x31ae14e02000     0x31ae14e03000 rw-    1    0   5   0 CN--- vn /usr/jails/basejail/base_amd64_amd64_13.2/libexec/ld-elf.so.1
  989     0x31ae14e03000     0x31ae14e04000 rw-    0    0   1   0 C---- sw
  989     0x7fffffffe000     0x7ffffffff000 r-x    1    1  59   0 ----- ph

Whoops! The paths arguably aren't supposed to leak into the jail like this (and with other commands I've tested, they don't).

The cause

I haven't probed very deeply into the cause due to a lack of time, but I have a suspicion it's caused by the kernel not sanitising paths somehow.

Non-mitigations

Although I use the term “mitigation” very, very loosely, I figure it may be helpful to document what can help if you care about this.

Things that do not help: – Disallowing kmem and /dev/io in the jail – Disallowing procfs in the jail – Setting enforce_statfs to 1 or 2 – sysctl security.bsd.unprivileged_proc_debug=0 in the host

Mitigations

Things that do help: – This only works if the user is root in the jail; disallowing root access in your jails may help (although this does make management a pain), and securing your jail against root exploits

Conclusion

This probably isn't a real vulnerability or problem in practise. I doubt it even deserves a CVE number. I don't think this could lead to any effective compromise or escape from the jail.

Nonetheless, it's a bug that should be fixed, IMO. If anything else, at least fixing it would follow the principle of least astonishment.

— Elizabeth Ōkami (Elizafox) Fedi (elsewhere): @Elizafox@social.treehouse.systems Tip jar: PayPal || CashApp || LiberaPay

I spent literally all day yesterday trying to figure out how to get a jail to route an IPv4 IP given to me by Vultr using vnet (I was having bizarre issues with IPv6 and the host stack; vnet fixed them).

It sounds like an easy problem, and to people who are super experienced... it probably is, and the answer is obvious in hindsight. But even 16 years of BSD experience couldn't help me here.

The problem in detail

The problem was routing an additional IPv4 IP that Vultr gave me, that wasn't in the same subnet as my main IP. It works fine on the host without issue:

ifconfig <external_interface> inet <second_address> alias

That's because the default route is already configured.

You'd think that in the jail, it'd be a matter of doing the same and it'd all Just Work™. Nope!

(Note with the below: not all attempts are logged, just the major ones I remember... I tried a lot of things, for 8 hours)

Adding the route: try 1

When you try it in the jail, like so:

route add default <host_gateway> -iface eth0

You get an error like:

route: writing to routing socket: Network is unreachable
add net default: gateway via fib 0: Network is unreachable

Bummer.

So I tried this in the jail:

route add <host_gateway> -iface eth0
route add default <host_gateway>

But nothing would route out of the jail.

Adding the route: try 2

I even tried this in the jail:

route add -net <host_gateway>/<host_subnet> -iface eth0
route add -host default <host_gateway>

And that was even worse. Now everything said “no route to host.” Gah.

I also kept getting this weird issue where I'd add a default route, and it would get corrupted into some gobbledygook in netstat -4rn like so:

Destination        Gateway        Flags Netif Expire
0.0.0.0&0x68150581 104.207.142.1  US    eth0
104.207.142.0/23   link#2         US    eth0

Maybe some kind of bug?

Adding the route: try 3

I went back to the former solution, and did tcpdump on the host. I was seeing traffic coming out of the jail, but it wasn't coming back. I could arping the host, and the gateway, but still couldn't route things.

So I figured it was a host issue.

I tried this on the host (not the jail):

sysctl net.inet.ip.forwarding=1
route add -net <second_ip> -inet bridge1

Nope.

Adding the route: try 4

At this point I was super confused. So in desperation, I even tried this on the host:

route add -net <second_ip> -inet epair1a

Still nothing.

Adding the route: try 5

I was pretty much despondent at this point. I had spun my wheels on this problem for 8 hours, brainstorming answers, trying literally everything I could think of, picking other's brains who were just as confused as I was.

So in an act of extreme desperation, I tried the one thing I hadn't tried on the host:

route add -net <second_ip> -inet <external_interface>

And then...

It worked.

Holy crap, it worked. I bowed down, thanked the heavens, and felt so much relief, I went and made Taco Hamburger Helper (I'm poor, okay?).

Making it all work

So here's how you can make this work in your environment, too, on Vultr and probably other hosting providers, if you're in the same situation:

Jail

cat >>/etc/rc.conf <<EOF
static_routes="default_router"
route_default_router="-host <host_gateway> -iface eth0"
defaultrouter="<host_gateway>"
ifconfig_eth0="inet <host_ip>/<host_subnet>"  # For me it was /32
EOF
route -host <host_gateway> -iface eth0
route default <host_gateway>

Host

cat >>/etc/rc.conf <<EOF
gateway_enable="YES"
static_routes="jail0"
route_jail0="-host <second_ip> -iface <external_interface>"
EOF
sysctl net.inet.ip.forwarding=1  # This just does what the line in rc.conf does on reboot
route add -host <second_ip> -iface <external_interface>

Addenum

If you have a provider that restricts the original MAC where something came from, you can replace <host_gateway> above with your host machine's IP. I tested that, and it all Just Works™. It should then route through your host machine to the outside world, and the jail's MAC in theory shouldn't be visible.

Conclusion

I hate IPv4 more than I hate IPv6 at this point. It's always been like this, whereas IPv6 has mostly been pretty good (minus ISP/modem issues... I once had a horrible Siemens DSL modem that wouldn't pass 6to4, but that's a story for another day).

— Elizabeth Ōkami (Elizafox) Fedi (elsewhere): @Elizafox@social.treehouse.systems Tip jar: PayPal || CashApp || LiberaPay

I get lonely a lot.

I mean, it's natural. I live alone.

I sort of got alienated from most of my friends here due to my own mistakes and missteps (although I cut off a lot of toxic people too). Those are mine to live with. But I have a few left here, and they've stuck by me.

It's probably for the better. A lot of them were just dead weight to me.

I know I need to rebuild my friend circle.

Being comfortable with yourself

I think something I've learnt how to do throughout all this is how to be comfortable with just me. I haven't lived alone ever in my life, until now. It's definitely an interesting experience.

I feel like it's a little isolating, but it's fine. It's teaching me valuable lessons about myself, and helping me grow more comfortable in my own skin. I really needed this, even if I didn't want it.

Will I ever live with someone again?

🤷‍♀️

I don't know what the future holds. I know right now, I'm not looking for new roommates, especially because the last one was an utter disaster, for me and for the people I was close to (and this is partially how I lost them).

I do know this: living alone means I don't have to live up to anyone's expectations or anything.

— Elizabeth Ōkami (Elizafox) Fedi (elsewhere): @Elizafox@social.treehouse.systems Tip jar: PayPal || CashApp || LiberaPay

I wanna talk a bit about something I discussed in therapy.

Guilt alone changes nothing. It doesn't help you, nor the people you've hurt.

What matters is empathy.

Guilt leads to self-pity.

The only thing guilt leads to, is self-pity.

Self-pity is not constructive. In fact, it is incredibly destructive, and leads to fatalism. All you do when you pity yourself is proclaim, “it cannot be helped; I clearly cannot change, because I am a bad person.”

This is false and leads you to repeating the same patterns over and over.

Empathy leads to change

Put yourself in the shoes of the people you hurt. Do you genuinely think they want you to punish yourself repeatedly as penance, and feel endless remorse, or do you think they want you to change and not do it again?

I'm willing to bet it's the latter.

Wallowing in guilt will only make things worse. What good does self-punishment do if you've made no commitment to avoid repeating the mistake?

You're probably not a bad person

You have much to offer others. You may do bad things, but so do we all. The mark of a good person is one who learns from their mistakes and puts in the effort to change their behaviour.

Guilt alone is neutral. Most people experience it. It isn't anything special, and as I said above, it doesn't help.

Nothing can substitute actions.

As my Latin teacher said: results, not excuses.

— Elizabeth Ōkami (Elizafox) Fedi (elsewhere): @Elizafox@social.treehouse.systems Tip jar: PayPal || CashApp || LiberaPay

I wanna vent a bit about dependencies and their hidden cost.

We all know the usual Dependency Hell problems, but there is a much more subtle problem, one I've run into time and time again.

Abandonware

Oftentimes, you run into a library (call it a crate, package, egg, gem, you could call it a poopsock for all I care), and it turns out to be abandoned and hasn't been updated in years. Worse, it may have bugs that you can't work out. So you're stuck forking it, or just copying the code and maintaining it locally in a sort of de facto fork. Yuck.

Variable quality

The biggest problem I've found, however, is variable quality. Oftentimes you think you've found this great library, that meets all your needs... and then you discover it has a terrible interface, or terrible documentation, or is riddled with bugs, or is designed for a completely different application domain.

Gah.

This is literally the worst. It's super annoying too, when the library implements functionality you really don't want to waste too much time implementing yourself, or handles a lot of boilerplate, or what have you.

The case for “batteries included”

I appreciate Python's approach (that they're seemingly abandoning gradually) of “batteries included.”

Stuff included in the standard library usually has many, many eyes on it. It gets audited frequently. It gets reviewed more often. And it's guaranteed not to break, it will work essentially “forever” or until it's deprecated (which you will get plenty of warning about).

Even if nobody is “touching” the code, code doesn't magically stop working when you're not looking at it. As long as bugs get fixed, and it does what it needs to do, it doesn't matter.

If wishes were fishes

I wish Rust's standard library was less minimalist for this reason. But I guess I can dream.

— Elizabeth Ōkami (Elizafox) Fedi (elsewhere): @Elizafox@social.treehouse.systems Tip jar: PayPal || CashApp || LiberaPay

Stop repeating mainstream news for clout.

This is a short rant.

What the title says. I don't want to have to unfollow people, but I will.

I'm sick of hearing the same bad news forcibly injected into my brain.

May I refer you to Death Grips' take on this?

— Elizabeth Ōkami (Elizafox) Fedi (elsewhere): @Elizafox@social.treehouse.systems Tip jar: PayPal || CashApp || LiberaPay

Some people ask me this, and if you don't know me well, there is a reason they ask this.

So this will function as a sort of “FAQ” about it.

How do I pronounce it?

Many people get this wrong.

It is pronounced /əˈlaɪzə.fɒks/ (eh-lie-zuh-FOCKS).

What's the deal with the Eliza/Elizabeth vs Elly thing?

I have always preferred those close to me call me Elly. Those I don't know very well should always call me Eliza or Elizabeth. Professionally, I go by Elizabeth.

This may seem unusual, but think about how many people have nicknames like this. “I'm Thomas, call me Tom,” “I'm Cynthia, call me Cindy,” etc.

It's a shame English doesn't have T-V distinction anymore. That would be cool. My name is kinda like that, though, with “Elly” being the “T” form, and “Eliza”/“Elizabeth” being the “V” form.

Side note about Early Modern English

If this were Early Modern English, this would be a relevant style guide:

  • T form: “Elly, I'm speaking to thee!”
  • V form: “Elizabeth, I'm speaking to you!”
  • T form: “Elly, what art thou doing‽”
  • V form: “Eliza, what are you doing‽”

But I don't want to get too deeply into the weeds of Early Modern English conjugation and all that.

What forms of your name are acceptable?

As stated above, Elly is preferred if we're close or if I ask you to call me that; otherwise, Eliza or Elizabeth.

Please do not call me “Liz,” “Lizzie,” or any other variant.

If you require disambiguation with another Elizabeth/Eliza/Elly, ask me for a preferred form. I'm not unreasonable.

“Why are you so picky about capitalisation?,” or, “How do I capitalise your name?”

The style of my name is invariant: the first letter is capitalised, the rest is lowercase.

Acceptable variants: – Elly – Eliza – Elizabeth

Unacceptable variants: – elly – ELLY – ELIZA – eliza – eLiZa

If you're just shitposting though, I probably won't get my shorts in a wad about it. I'm not that stubborn.

What's the deal with your British English spelling?

This has nothing to do with my name, but I get asked that a lot anyway.

That's how I was raised to spell things.

How did you come about your name?

I picked it out of a hat. Literally. I just got a baseball cap, filled it with random slips of paper with names I liked, and chose it.

I chose it when I was about 18 years old or so, so a very long time ago.

What are your pronouns?

This section is tentatively normative, but subject to change.

This is tangential to my name, so I'll include it.

I've experimented with different pronouns (and even trying just my name) in the past, I'm not totally happy with the status quo, but this is the happiest I've been in a while, so we'll go with this for now.

You may call me she/her, or they/them. Either is fine. I have no real preference.

I used to be pickier about this, asking strangers to call me they/them and for those close to me to use she/her, but I've softened my stance since. I just found I didn't mind being called she/her.

What's your middle name?

Aurora.

I don't want to explain how I came about that name in a blog post, that's private.

It follows the same style guide as the rest of my name, first letter always capitalised, the rest lowercase. Please do not shorten it.

It used to be Jennifer, but that's long since deprecated.

What's your last name?

It's at the top of the blog, dummy!

It's Myers.

This last name is descended from a Scottish planter who became a mayor of a town in what is now Northern Ireland. However, I do not really identify with this part of my heritage, it's just where my last name comes from. I may change it in the future.

What is your name in other languages?

In Japanese, I prefer the name 直美. This was given to me by my sensei who taught me elementary Japanese.

In French, Elisa and Elisabeth are acceptable variants. Elly is the same, though I usually spell it Ellie in French.

In Spanish and Portuguese, Elisabeth/Isabel/Isabella is acceptable. Elly is the same, though Isabel is fine for an informal version too.

Otherwise, ask me!

Side note on T-V distinction

In languages like French with T-V distinction, I ask that those who don't know me use the V form, and use the T form if we know each other or if that's the standard form in the language. They're usually the same rules that apply for Eliza/Elizabeth vs. Elly. All V forms should use “Eliza” or “Elizabeth” or a localised variant, and all T forms should use “Elly” or a localised variant of my choosing.

— Elizabeth Ōkami (Elizafox) Fedi (elsewhere): @Elizafox@social.treehouse.systems Tip jar: PayPal || CashApp || LiberaPay

I think Rust needs a GC type, like what @ was supposed to be.

I don't mean a reference-counted type, I mean an opt-in garbage-collected type, akin to Rc or Arc.

My case

It's quite simple.

Cyclic data structures

Sometimes you have cyclic data structures in Rust. Said reference cycles mean you need to manually implement Drop. Sometimes you find yourself fighting the borrow checker over these cycles.

It's horrific pain and nobody should have to go through it.

We can avoid all this by having a Gc or Agc type that doesn't care how many cycles there are, it just does the right thing.

Garbage-collected languages

Implementing a garbage collector is basically mandatory for implementing any garbage-collected language, like JavaScript.

For Rust to be usable in these contexts, you either have to implement a GC yourself (which is horrific pain), or use an existing crate (none of them are ideal).

A built-in Gc and Agc type would help everyone in this.

Avoiding dangling pointers on Drop

When dropping to the level of pointers (which you basically have to do to implement anything with reference cycles), you run the risk of all sorts of problems associated with them.

I didn't choose Rust only to be forced into using it like C! It brings back the spectre of memory errors, use-after-free, off-by-one, etc.

We can avoid this whole mess with a Gc type.

But isn't there the gc crate?

Well, yes. But it can be quite a pain to use, and it's not as nice as something integrated into the language.

It also isn't thread-safe. Ideally, a GC type should be thread-safe.

But GC is evil!!!!!11111oneone!1!11

Yes, I know the arguments against GC. I am aware they tend to be non-deterministic, have the embarrassing pause, etc.

But I digress

For 99% of use cases, you absolutely do not need a GC. There's absolutely no reason to use one most of the time and in most applications.

But when you need one, you need one.

I genuinely hope this can become a thing someday in Rust.

— Elizabeth Ōkami (Elizafox) Fedi (elsewhere): @Elizafox@social.treehouse.systems Tip jar: PayPal || CashApp || LiberaPay

I'm kind of struggling to pay the bills right now. I'm still looking for work.

If you want to help, there's a few ways.

Employment

The main way you can help me is by employing me.

I'm looking for tech work in Seattle (specifically software engineering or systems administration, open to DevOps positions), although I will relocate if the price is right. I'm primarily looking for remote/WFH, but I will work at an office if you absolutely insist. I will give my résumé on request.

I am also accepting contracts. If you need something done in a project, FOSS or not, drop me a line. I'll happily do it for you. My rates are relatively reasonable. We can negotiate it.

If you want to contact me about employment opportunities, drop me a line.

Background

I'm a software engineer/system administrator/devops person with a wide variety of experience, particularly in systems programming. For languages, I know Rust, Python, C, C++, a bit of Java, and I can probably learn your weird language in short order. For systems, I am experienced with Linux (Debian, Ubuntu, Arch, Gentoo, Fedora, you name it), FreeBSD, NetBSD, and a bit of Windows.

I am a very, very fast learner!

Tip jar

This is the less preferred option, but it still helps me a lot.

You can toss a few bucks in the tip jar: PayPal, CashApp, or LiberaPay.

— Elizabeth Ōkami (Elizafox) Fedi (elsewhere): @Elizafox@social.treehouse.systems Tip jar: PayPal || CashApp || LiberaPay