Asus RT-AC56U

Illustration

As I was getting tired of crowded 2.4 GHz band in my neighborhood, I started looking into newest 802.11ac routers. I was after something small, dual band, and with support for Tomato (or DD-WRT) firmware (history taught me that manufacturer’s firmware sucks).

One device that fitted description was Asus RT-AC56U. Having owned Asus’s WL-500g, WL-300g, and still owning WL-330gE I was quite confident that hardware will be good, LEDs will be blue, and original firmware will be rubish. I also expected to get unbrickable device with a lot of community support. [2014-04-19: Of course I have managed to brick this one. I should learn to keep my mouth shut.]

Hardware-wise this is AC1200 category, dual-band (2.4 GHz and 5 GHz), dual-stream router with 4 gigabit ethernet ports and two USB ports (one is 3.0). All is driven by BCM4708, dual core 1 GHz CPU (down-clocked to 800 MHz), 256 MB of RAM, and 128 MB of flash. As home routers go, this is a beast. Not the fastest beast, but beast nevertheless.

As I plugged it in, I was enchanted. This is my first home router where I didn’t need to open a case and modify LED brightness myself. It is nice subdued blue light that won’t light-up your house like a Christmas tree. It is just perfect intensity. And yes, I am easily amused. :)

I haven’t been checking Asus firmwares for a while so it came as a surprise how open it has become. Yes, it has always been an open source but best thing you could count on was to get raw sources every few months. Asus now bases firmware on AsusWRT source code that is obtainable few days after firmware gets published. It even contains (accurate) setup instructions for compiling that code yourself.

I am pleasantly surprised with this development and it shows results. While usually only firmwares worth having on router were DD-WRT and Tomato, now we must take Merlin into consideration too. Probably due to all that liveliness, Asus own firmware actually doesn’t suck. Mind you it is not as good as any of these alternatives but it is actually possible to use it without swearing.

Setup of a device is quite simple and practically leads you by hand toward getting your Internet connection. Beginners will probably leave it there and be happy. Advanced users have many more things to configure, whether it is IPv6, disk sharing, or VPN. Most settings can even be applied without losing connection. Really nice.

Not all things are perfect unfortunately. For one, 2.4 GHz stability and range is between bearable and just awful. Irony would have it that, in my household, Asus’ own N56VJ laptop (Atheros AR9485WB) is almost unusable even just two meters away. For a minute it would have low speed connection (i.e. 2-3 Mbps), then it would just stall for a few seconds, recovering to 2-3 Mbps in ten seconds or so. Then it would stall again, repeating the cycle. And it is not because of location; kiddie WL-330gE router handles the very same location without any issue…

Asus team is looking at it and there are promises of a new firmware that might make things better but I wouldn’t hold my breath here. I have tried their newest beta firmware and results are just marginally better. I have tried completely alternative firmwares and everything is as bad as with original one. 2.4 GHz devices I have with Intel and Broadcom chipset are behaving much better but nowhere near how they should. I would say that this is more probably a design issue that might or might not be dealt with in a newer hardware revisions. Those who already bought one are probably out of luck.

All taken in consideration, I am very satisfied with purchase. Most devices I have are 5 GHz capable and they work wonderfully through my whole apartment. In furthest location I still have download speed exceeding 50 Mbps. Maybe it would go faster but my Internet pipe cannot handle it. Whether it will be as good when 5 GHz band gets congested as 2.4 GHz one well see in future, but I will enjoy it while it lasts.

Would I recommend it to someone else strictly depends on how bad do they need 2.4 GHz. If you are shooting toward 5 GHz this device is probably best bang-for-buck. For $120 you get a really capable CPU, lots of memory, and a variety of firmwares that can give you whatever functionality you desire. For somebody who likes tinkering with network this is god-given.

Alternative Boolean Syntax

I got into discussion with a friend on what is the best way to express boolean-like value in a C# initializer. Whole discussion was spurred by following piece of code (ok, not exactly this one, but similar enough):

var x = new FieldCollection(**true**);

This perfectly valid line has a magic boolean argument whose function is not immediately clear. Syntax-wise code is fine but readability does suffer. Neither one liked how this looked and we went into discussion about refactoring. First one was introducing an enumeration class:

var x = new FieldCollection(**FieldDuplicate.Allow**);

This is an usual approach to readability argument. Create an enumumeration that has (more or less) reasonable names and then use that as an argument. It allows for better readability at cost of a bit more coding.

But C# has something I find better. You can use named arguments to have greater visibility without any extra coding:

var x = new FieldCollection(**allowDuplicates: true**);

Maybe it is not as clean as a dedicated enumeration but I find it works for me. It doesn’t require any code changes inside of a class. It doesn’t require an extra enumeration declaration. And it works even when you don’t have access to code of a class. All that is needed is a bit of discipline upon calling code.

And programmers always have abundance of discipline… :)

Setting Up Private Internet Access on Mint

Illustration

When I published post about OpenVPN on CentOS most common comment was "How to do that on some more user-friendly distribution. Well, you don’t get much more friendlier than Mint 16 (Petra).

Before starting with anything we need to install OpenVPN package. This is done via Menu, Administration, Software Manager. Just type OpenVPN and install first thing you get back (yep, this is great piece of security advice ;)).

First we can do the easy stuff. Download PIA’s OpenVPN configuration files and extract it to directory of your choice. I kept them in /home/MyUserName/pia.

Next easy step is setting up DNS resolving. For that we go to Menu, Preferences, Network Connections. Just click edit on connection you are using and go to IPv4 Settings tab. Change Method to Automatic (DHCP addresses only). Under DNS servers enter 209.222.18.222 209.222.18.218 (PIA’s DNS).

All other commands are to be executed in terminal and most of them require root privileges. It might be best if you just become root for a while:

su - root

Next step is getting configuration in place (replace username and password with yours):

cp /home/MyUserName/pia/ca.crt /etc/openvpn/ca.crt
cp /home/MyUserName/pia/crl.pem /etc/openvpn/crl.pem
cp /home/MyUserName/pia/US\ Midwest.ovpn /etc/openvpn/client.conf

sed -i "s*ca ca.crt*ca /etc/openvpn/ca.crt*" /etc/openvpn/client.conf
sed -i "s*crl-verify crl.pem*crl-verify /etc/openvpn/crl.pem*" /etc/openvpn/client.conf

echo "auth-user-pass /etc/openvpn/login.pia" >> /etc/openvpn/client.conf
echo "mssfix 1400" >> /etc/openvpn/client.conf

echo "^^username^^" > /etc/openvpn/login.pia
echo "^^password^^" >> /etc/openvpn/login.pia

chmod 500 /etc/openvpn/login.pia

Now we can test our connection (after we restart network in order to activate DNS changes):

/etc/init.d/networking restart
openvpn --config /etc/openvpn/client.conf

Assuming that this last step ended with Initialization Sequence Completed, we just need to verify whether this connection is actually used. I found whatismyipaddress.com quite helpful here. If you see some mid-west town on map, you are golden (assuming that you don’t actually live in US mid-west :)).

Now you can stop test connection via Ctrl+C in order to properly start it. In addition, you can specify it should start on each system startup:

service openvpn start
echo "AUTOSTART=all" >> /etc/default/openvpn

Lastly you can think about firewall and disabling default interface when VPN is not active. Of course, in order for things to work, we still need to allow port 1194 toward our VPN server and DNS:

ufw default deny incoming
ifw default deny outgoing
ufw allow out on tun0
ufw allow out 1194/udp
ufw allow out on eth0 to 209.222.18.222 port 53 proto udp
ufw allow out on eth0 to 209.222.18.218 port 53 proto udp
ufw enable

And that is all.

PS: It is not a déjà vu, article is really close to how it was set on CentOS.

[2016-10-01: Removed auth-nocache directive as it didn’t play nice with auth-user-pass.]

Growing a ZFS Pool

Illustration

As I was building my media server, I decided I must have support for both network file sharing and DAAP protocol. That way I could (comfortably) listen to my media collection using both my PC and my mobile phone. That simple requirement and fact that I had some experience with FreeNAS 0.7 drove me to NAS4Free.

I installed it in VirtualBox with two virtual drives; one 512 MB and another 2 GB. On smaller one I did embedded install of NAS4Free. Second one I formatted as ZFS (a.k.a. single *nix file system that doesn’t suck on power loss) and assigned to a single ZFS virtual device which was in turn assigned to a single ZFS pool. Both DAAP and samba were then forwarded to this share for their consumables.

Since I naively allocated only 2 GB I soon stumbled upon topic of this blog post. How do I increase my ZFS volume?

Increasing virtual disk is really easy and there is probably handful tools for every disk type (VHD in my case). I decided to use VirtualBox built-in vboxmanage tool (found in VirtualBox’s directory; don’t forget to turn off virtual machine):

VBoxManage.exe modifyhd "D:\Media.vhd" --resize 8192
 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

While this was simple enough, it didn’t resolve anything. Next boot-up showed that ZFS still assumed 2 GB as size of a pool (at Disks, ZFS, Pools). If there was only a way for ZFS to recognize disk was bigger…

Fortunately there was just such a command. I went to Advanced, Command and executed following line:

zpool online -e Media-Pool ada1

Media-Pool was name of ZFS pool I was increasing and ada1 was actual physical disk that pool was located on. And that was it, my disk was increased painlessly and without any need for copying data around (except for backup purpose, of course). While it was nowhere close to comfort of using mouse to perform this task in Disk Management, it wasn’t too bad either.

PS: This post assumes that you know how to use NAS4Free. If you don’t use it, do try it out. You’ll love it.

PPS: Essentially same procedure works for FreeNAS or any other situation where you have virtualized disk drive with ZFS pool on it.

[2018-07-22: NAS4Free has been renamed to XigmaNAS as of July 2018]

Syntactic Sugar Does Make a Difference

Most of the days I have my life split between Java and C#. Work on one during the day, enjoy the other during the night. Some things I like in one language, some I prefer in other; it all depends on situation. But there is one feature I miss daily in Java. It is the var keyword.

Simplest scenario would be:

var x = new Something();

In this case var does not signify some new data type but it simply says to compiler to infer most appropriate type on its own. It is not variant data type by any stretch of imagination (check [dynamic](http://msdn.microsoft.com/en-us/library/vstudio/dd264736.aspx) for that) because var still statically assigns a type. Finally compiled code is actually equivalent to:

Something x = new Something();

In this, most basic scenario, it is already quite helpful in avoiding repetition. But it gets better. If you are dealing with loop, you don’t need to remember which kind of collection you are going in:

foreach (**var** item in foo.getItems()) {
    item.doSomething();
}

Assuming getItems() returns IList<MyItem>, this code might get compiled as:

foreach (**MyItem** item in foo.getItems()) {
    item.doSomething();
}

As long as MyItem type contains doSomething(), everything just works. If getItems() returns list of String, compile will fail (doSomething() is not a method of a String, at least not in current Java/C# version). If you ever refactor your code to use some other class, compile will still work as long as it contains same methods used elsewhere in code.

And that is the case where I miss it in Java the most. If I work with someone else’s classes and it is obvious that some sort of collection is returned, why cannot language figure out this for me? Why do I need to tell it, for even most basic cases, what exactly I need? Just so it can triumphantly say that my type doesn’t match what it expects? If compiler is smart enough to tell me my return type sucks, it should be smart enough to fill the data type itself.

While this var keyword does save me some typing its primary benefit comes from a more relaxed workflow. It helps me get over gritty, boring, ultimately unimportant, details into the code that actually matters. It preserves my flow of thoughts and it does make me more productive.

I see this feature as a major reason why I find C# more comfortable language than Java. It is not (just) about this particular syntactic sugar. It is about a philosophy. While Java prefers cleanliness of language, C# makes work easy.

PS: And don’t let me get started about how var is used with anonymous types, a distant dream in Java.