Saturday, March 19, 2011

Powershell script to enable windows to capture localhost traffic in wireshark

If you want to understand why the following scripts work read this post. Otherwise just paste the following into an elevated powershell window:

Setup windows networking to allow localhost capturing in wireshark:
# Find the network configuration that has the default gateway.
$defaultAdapter = Get-WMIObject Win32_NetworkAdapterConfiguration | ? {$_.DefaultIPGateway}
if (@($defaultAdapter).Length -ne 1) {throw "You don't have 1 default gateway, your network configuration is not supported" }
# Route local IP address via the default gateway
route add $defaultAdapter.IPAddress[0] $defaultAdapter.DefaultIPGateway
Write-Host "Start capturing on localhost by connecting to $($defaultAdapter.IPAddress[0])"

Return windows networking to normal configuration:




# Find the network configuration that has the default gateway.
$defaultAdapter = Get-WMIObject Win32_NetworkAdapterConfiguration | ? {$_.DefaultIPGateway}
if (@($defaultAdapter).Length -ne 1) {throw "You don't have 1 default gateway, your network configuration is not supported" }

# Stop routing localhost traffic to the router.
route delete $defaultAdapter.IPAddress[0]

Remember, you won’t see traffic to localhost (127.0.0.1) but traffic to your network adapter’s IP address as listed in the script.


Thursday, March 17, 2011

How did we get a 53 byte packet size in ATM?

I'll be honest, I don't know squat about ATM, but I was having lunch with this fellow, and he told me the story of the 53 byte ATM packet. 

You can find more details on Wikipedia, but here’s the synopsis:

(Disclaimer: I’m not an expert in ATM; nor am I trying to teach you technical details about ATM networks; so I’ll hand wave and trade off accuracy for simplicity. For example, ATM does have variable sized packets which it divides into cells, and it is the cells which are 53 bytes long. However, since the closest thing to a cell in common networks is an Ethernet packet, I’ll simply refer to cells as packets.)

ATM is designed to be shared between data network applications, and voice network applications(+).

In data networks we want large packets because this gives maximum efficiency.  This is because each packet has a fixed size header and thus the more data you can transmit per packet , the higher your ‘real’ throughput.

For voice networks we want to reduce latency.  Latency is the fancy word for delay.

If voice packets are delayed, you’ll hear them at the receiver as an echo; this is un-acceptable and thus to mitigate delays you’d need to install an echo canceller (++).
In the USA, the country was big enough (+++) that no matter how small the packet size was chosen to be, you’d always need echo cancellers – therefore America proposed an optimal packet size of 64 bytes.

In France, which was much smaller then America, if the packet size was chosen to be 32 bytes the packet could get from one end of the country to the other without enough delay to require echo cancellers. Thus France pushed for a 32 byte packet size.

To achieve consensus, a compromise was required and a 48 byte payload size was chosen.  This did not meet France’s need, nor was it optimal for the US; however, this is what happens when you require consensus.
But wait you ask, where do the last 5 bytes come from? Ah, the committee was very concerned about the overhead of the packet header, so the committee decided the packet header could not exceed 10% of the packet size, thus the committee chose a 5 byte header.  48 + 5 == the 53 byte ATM packet size; which is the optimal solution for no one.

Notes:
(+) At the time ATM was designed, people made long distance calls over voice networks.
(++) If you’re old enough to remember the early days of skype, you needed to use headphones otherwise the echo was unbearable. Today computers are powerful enough to do echo cancellation without blinking.
(+++) Compute big enough by calculating time required for light to traverse the USA.

Saturday, March 12, 2011

The cloud lets you evaluate the cost of performance optimizations

One of the things I love about cloud computing is you can put an honest price on computing time.  You can than balance the human engineering time required to optimize code (and often have more complex code) vs just paying for the cloud to do it.  The Zillow rent estimate post speaks to this brilliantly:

We implemented the Rent Zestimation process as a software application taking input from Zillow databases and producing an output table with about 100 million rows.

We deploy this software application into a production environment using Amazon Web Services (AWS) cloud.  The total time to complete a run is four hours using four of Amazon EC2 instances of Extra-Large-High-CPU type.  This type of machine costs $1.16/hr.  Thus, it costs us about $19 to produce 100 million Rent Zestimates which is the same as a 3-D movie ticket or about 5 gallons of gasoline in New York City today.

A few things to note about this quote:

  • If your data processing can be done in parallel, you’d have the same cost but at a lower time since you can run all instances in parallel
  • If your data processing must be done in serial, and you want results faster than the largest instance can compute them, buy some coffee you’ll be up doing optimizations.
  • Gas prices are through the roof in New York

Friday, March 11, 2011

Using LINQ to XML from F# (and a bit of duck typing for fun)

So you want to use XML from F#? here are the tips and tricks I discovered today to clear my roadblocks.

Tip 1: Reference the System.XML assembly from FSI so you play with the REPL. To do this I add the #r in block comments at the top of the file  like so:

(* Press Alt-' to send the below to the interpreter.
#r @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Xml.Linq.dll"
*)
open System.Xml.Linq
Tip 2: F# doesn’t perform implicit conversions. Lets assume you’re translating the following C# code:

var xelements = XElement.Parse("<myXML/>");
var interestingElements = xelements.Descendants("myXML");
The naive translation below doesn’t work because XElement.Decendants doesn’t take a string, it takes an XName

//FAILS to compile This expression was expected to have type XName but here has type string 
let interestingElements = xelements.Descendants "myXML"
The reason the above code works in C# is because an implicit conversion operator exists and is called. However in F# implicit conversions are not called, and you have to call them yourself, something like the painful to read:

let interestingElements = xelements.Descendants <| XName.op_Implicit "myXML"; 
Now, it turns out we can use duck typing to make an implicit conversion operator (this is mentioned lots of places on the web but I’ll repeat it for succinctness)

// Create an implicit conversion operator, it's inline which means it will work on any types that support the implicit conversion.
// This is duck typing.
let inline convert_implicit(arg : ^source) : ^target = ((^source or ^target) : (static member op_Implicit : ^source -> ^target) (arg))
And finally we can write the code I needed:

let interestingElements = xelements.Descendants <|  convert_implicit "myXML"; 

Wednesday, March 9, 2011

Supply, demand and the trackball market.

The author of this blog is a devout trackball man, and as any devout trackball man can tell you, it has been trying times for trackball users in the last few years. You see trackballs were never really in style, and no one has made a new trackball for a while.  It's so bad out there that one of my favorite trackballs now sells used for over 200$ and new for 500$.



Crazier than that you can send away to get your trackball reconditioned on ebay, for a whopping 100$, where they'll clean it and put on a new cord.  



Thankfully, there has been movement in the trackball market. Logitech released a new wireless trackball!!! So far I love the tiny USB receiver (which fits in the trackball when not in use). I wish the trackball was larger, but we’ll see how I enjoy using it over the coming months.

Monday, March 7, 2011

Decoding Ubuntu Version Numbers

I've always been fond of the Ubuntu code names, "breezy badger" and  "warty warthog" are some of my favorites. I know the code names are in alphabetical order, but I never understood how the Ubuntu folks got the version numbers. Why does 10.10 come after 10.04? Today I realized it's because the version numbers are release dates,  and releases are every April and October. So, this April's release "Natty Narwhal" will be 11.04.  Learn something new every day.  Oh and if you don't know what a  narwhal is,  it's  worth checking out.