How to read descriptions of software libraries

There is a certain language we use when describing software libraries. I find that often times there are kernels of truth behind it that are not apparent on the surface. Here is my glossary:

Simple – the project is incomplete. It is likely a clone of a more feature rich project that the author did not figure out.

Easy to use – will break the API in the next release

Featureful – bloated beyond belief

Stable – stale. It is likely that the project was abandoned or has a single maintainer that lost faith in it.

Powerful – has a complex API that only helps you in one specific use case. Prepare to write a wrapper around it

Advanced – requires intimate understanding of the algorithms used

Cross-platform – 90% cross platform. Get ready to write your own code to address the other 10%

Small – proof of concept not ready for prime time

Weekend project – a three week effort with glaring issues

Fast – is barley usable for running benchmarks

Lightning fast – hello world

Scalable – see “fast”

Smart – has lots of magic you won’t understand

Complete solution – “do as we say, or you will suffer”

Engine agnostic – there is one correct engine and a dozen half-baked unsupported ones

Does one thing well – does one thing. There is probably a command line tool that does this better.

Fast growing – will break the API and the fundamental paradigm of the project with the next release

Well documented – documentation is either out of date or the project is abandoned. See also “stable”

Promsing – no documentation

Like X but for Y – bad port of a popular solution to a domain where it is not applicable

Web scale – will lose your data when you turn away

Like MySQL only 100x faster – a memcached clone

NoSQL – a vast array of different data stores from simple key-value in-memory solutions, to complex distributed batch processing systems

Demonstrates the power of underlying technology X – first project with technology X

Industry standard – obsolete. There are likely better solutions.

Obviously this is somewhat tongue-in-cheek. There is a lot of great software out there and not all of it fits these stereotypes. However, next time you are about to describe a library as “a smart, fast scalable X for Y” do the translation in your head first and have a self-aware chuckle first.

TI MSP430 LaunchPad links roundup

Lately I’ve been playing with the TI MSP430 LaunchPad. This post is a collection of links to resources that were helpful to me for getting started. If you happen to use Ubuntu and want to write and compile C directly, here’s how you would do that: Step 1: Install necessary packages via apt-get:
sudo apt-get install msp430-libc mspdebug msp430mcu binutils-msp430 gcc-msp430 gdb-msp430
Step 2: Write your code using your favorite editor/environment. Step 3: Compile the code using the msp430-gcc executable:
$ msp430-gcc -o main.elf *.c
Step 4: Flash the code onto the microcontroller:
mspdebug rf2500 'prog main.elf'

You need IPv6 now and here’s how to get it

The Internet is dead! Long live the Internet (v6)! You need IPv6. I need you to have IPv6 so you can view this website over the next generation Internet Protocol. If you and I both had IPv6, we would be able to forget about such inconveniences as NAT. We could video chat without having to have a separate server. We could share files directly. We could do a whole lot of really cool stuff.

Now, the question is: how do you get IPv6? Here is one way using SixXS and a Raspberry Pi.

This is my current method, since it is low cost and requires no special router setup. Basically, IPv6 packets are encapsulated into IPv4+UDP via the Anything-in-Anything protocol. UDP traverses NAT boundaries fairly easily and SixXS provides a very nice service so that you don’t have to manually tell them that your public IP has changed. Using this setup, I’ve basically created a generic IPv6 tunnel endpoint and router that I can connect to almost any LAN and it would automagically enable IPv6 on that network. Let me show you how:

1. Obtain a Raspberry Pi and install Linux on it. This is beyond the scope of this post, and documented well elsewhere. You can also use any other always-on device on your network, but I will assume you will get a Raspberry Pi for the purpose here.

2. Get an account with SixXS. This is a multi-step process where some steps require manual approval, but it goes pretty quickly. Once you have your account, request a tunnel and a subnet. For the reason, state something like “I want to get my local network IPv6 enabled”, but with more detail. Make sure to select the AYIYA type of tunnel.

3. Set your Raspberry Pi as a router:

$ echo "net.ipv6.conf.all.forwarding=1" | sudo tee -a /etc/sysctl.conf
$ sudo sysctl -p

4. Set up your firewall:

$ ip6tables -A INPUT -i lo -j ACCEPT
$ ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
$ ip6tables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
$ ip6tables -A INPUT -s 2001:4830:xxxx:xxx::/64 -j ACCEPT
$ ip6tables -A INPUT -s 2001:4830:xxxx:Yxxx::/64 -j ACCEPT
$ ip6tables -A INPUT -p ipv6-icmp -j ACCEPT
$ ip6tables -A INPUT -j DROP
$ ip6tables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
$ ip6tables -A FORWARD -p tcp -m tcp --dport 22 -j ACCEPT
$ ip6tables -A FORWARD -s 2001:4830:xxxx:Yxxx::/64 -j ACCEPT
$ ip6tables -A FORWARD -p ipv6-icmp -j ACCEPT
$ ip6tables -A INPUT -j DROP

Note that we are letting two IPv6 subnets through: 2001:4830:xxxx:xxx::/64 and 2001:4830:xxxx:Yxxx::/64. The one with the Yxxx is going to be the routed subnet. That’s the one that the rest of the devices on your network will use. The one with just the xxx will only have two addresses on it: ::1 (the remote end of your tunnel) and ::2 (your Raspberry Pi).

5. Make sure your firewall is enabled at boot time. This is easy:

Put the following into /etc/network/if-pre-up.d/ip6tables-load, and make it executable ($ sudo chmod 755 /etc/network/if-pre-up.d/ip6tables-load)

#!/bin/sh
ip6tables-restore < /etc/ip6tables.rules
exit 0

Now, put the following into /etc/network/if-post-down.d/ip6tables-save and make it executable ($ sudo chmod 755 /etc/network/if-post-down.d/ip6tables-save)

#!/bin/sh
ip6tables-save -c > /etc/ip6tables.rules
if [ -f /etc/ip6tables.downrules ]; then
   ip6tables-restore < /etc/ip6tables.downrules
fi
exit 0

For good measure, execute $ sudo /etc/network/if-post-down.d/ip6tables-save

6. Now that you are firewalled off, let’s bring up the IPv6 tunnel. All this takes is:

$ sudo apt-get install aiccu

Answer the questions about your login and password, then let the install finish. Check that you have IPv6 connectivity:

$ ifconfig
...
sit0      Link encap:IPv6-in-IPv4  
          inet6 addr: ::127.0.0.1/96 Scope:Unknown
          inet6 addr: ::192.168.1.225/96 Scope:Compat
          UP RUNNING NOARP  MTU:1480  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

sixxs     Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet6 addr: fe80::4830:xxxx:xxx:2/64 Scope:Link
          inet6 addr: 2001:4830:xxxx:xxx::2/64 Scope:Global
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1280  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:0 (0 MiB)  TX bytes:0 (0 MiB)
...

$ ping6 google.com
PING google.com(lga15s29-in-x01.1e100.net) 56 data bytes
64 bytes from lga15s29-in-x01.1e100.net: icmp_seq=1 ttl=53 time=44.2 ms
64 bytes from lga15s29-in-x01.1e100.net: icmp_seq=2 ttl=53 time=47.1 ms
^C
--- google.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 44.231/45.715/47.199/1.484 ms

7. Start using your IPv6 routed subnet. First, you will want to edit your /etc/aiccu.conf file. Here is the diff:

-#setupscript /usr/local/etc/aiccu-subnets.sh
+setupscript /usr/local/etc/aiccu-subnets.sh

Now, create an executable script at /usr/local/etc/aiccu-subnets.sh with the following content:

#!/bin/sh

ip addr add 2001:4830:xxxx:Yxxx::1/64 dev eth0

Then restart aiccu: $ sudo /etc/init.d/aiccu restart. Now, your eth0 will have its own IPv6 address in the routed (Yxxx) subnet.

8. Enable IPv6 for the rest of your LAN. This step is also very easy. We will install radvd ($ sudo apt-get install radvd) and configure it to advertise your routed network prefix. Create a file at /etc/radvd.conf with the following content:

interface eth0 { 
        AdvSendAdvert on;
        MinRtrAdvInterval 3; 
        MaxRtrAdvInterval 10;

        prefix 2001:4830:xxxx:Yxxx::/64 { 
                AdvOnLink on; 
                AdvAutonomous on; 
                AdvRouterAddr on; 

		AdvValidLifetime 30;
		AdvPreferredLifetime 20;
        };
};

Now restart radvd: $ sudo /etc/init.d/radvd restart. Now the rest of your LAN is IPv6 enabled. Enjoy.

2012-12-04 WOD: Kettlebell bonanza

Going forward, I’m going to post a few workouts that I am doing that day, mostly so I don’t forget them. Feel free to copy, comment, etc. Warmup: 250 meters on the rower or 1/4 mile run
  • 12 swings with 30#
  • 12 bear squats
  • 12 one-hand swing and switch 30#
  • 12 lunges with KB hand switch 30#
  • 12 getups
  • 12 hand-switch box push-ups
  • 12 box jumps
  • 12 sumo squat high pulls 30#
Rest every 4 rounds, as many rounds as possible in 30 minutes.

What to Bring to a Mud Run, Part 2

My last post about mud runs generated quite a few pageviews, so I figured I’d post a quick update. Hopefully, this info will be helpful to people doing mud runs in the future. I recently completed my second mud run (Zombie Escape at Panic Point), which was a great experience. Here is what I learned there.

First, in addition to all the other things you should bring (towels, change of clothes, water, cash and a distinctive bag), you should also bring a snack. My preferred is trail mix and fresh fruits. You’ll likely want to have something like a banana right before you run to make sure you have enough blood sugar to run fast.

Also, make sure that you bring all of these items with you to the race location. Leaving a change of clothes in the car is no good if you want to change after you shower. Panic Point had much better showers than the previous mud run I did, so this time I actually washed off. They also provided two tents, one for men, one for women, to change out of the muddy clothes. The bag check worked very well for me this time around so I felt no reason to keep all the things I brought in the parking lot.

Another interesting thing that I saw a lot of runners do is using head-mounted action cams. One guy actually had two of them, plus a tripod. I saw many videos (for example this one) on YouTube afterwards that look like they came from these cameras. I doubt it’ll get you to Sundance, but it’d be at least fun to share it with family/friends. There was also a very cool, but short official video.

Lastly, this time around my team made our own T-shirts. We used white cotton-polyester blend shirts and iron-on transfers printed on a high quality inkjet. Surprisingly the transfers held up really well, though the shirts are no longer white. The best part: the price. We paid about $5/shirt, as compared to others at the event who ordered them online for $20-$30.

Introducing LetSlide

I recently had the pleasure of using landslide to create a couple of quick presentations. The premise here is great: write what you want to say in Markdown, get elegant slides back. However, while I am familiar with how to set up Python, install things from GitHub, etc., many are not. To give the power of landslide to the people (and to use it for myself), I created (drumroll please), LetSlide. Here, you have a simple web interface to create landslide presentations, and a place to host the results. Give it a whirl and let me know what you think.

Two project sunset

I am sunsetting two of my pet projects due to lack of use. The first is LovelyCo.de. I never had time to market it properly so it got zero use since the launch.

The second, is DiscID DB. I was the only user of this project, and while it was a great experience, setting up and maintaining a public API and I learned quite a bit, I decided not to continue working on it.

If you have a particular interest in either of these two projects, please contact me via email (see the About page).