Under the hood

One of the most important reasons the Internet is both cool and interesting is its modularity. Different layers of the network model do their thing, without needing to care what the layers above or below them are doing. It makes writing Internet-based applications relatively straightforward, which means we get a lot of cool, shiny toys to play with. This is, of course, a Good Thing ™.

For technology geeks, though, this modularity also means that individual pieces of technology can be learned in relative isolation. You don’t have to know or care how (most of) the rest of the stack works in order to teach yourself a new piece of the puzzle.

(A brief and more-or-less-correct description of how the Internet does its thing follows. Feel free to read, skim, or ignore it; the “cool stuff” is below.)


There are generally two basic approaches to learning how the stack of Internet protocols works: “bottom-up” and “top-down.” At the bottom of the stack is the physical layer — the wires, fiber optic cables, or radiofrequency links that actually move the information around. The next few layers deal with the electronics that translate the information back and forth and get it where it’s going. Higher up are layers that handle authentication (where needed), and the Application Layer — which is concerned with actually doing the task at hand. Information travels up and down these layers every time any action is initiated on the Internet (or other TCP/IP network).

For instance, suppose you click on a link to this blog. Your browser, at the Application layer, translates this into a request to the appropriate web server (www.paleotechnologist.net). It then uses knowledge of HTTP (HyperText Transfer Protocol) to formulate a request in a way the webserver can understand. Once this specific, formal request is created, the browser passes it to your computer’s network protocol stack, which looks up the IP address of the webserver, packages the request into a TCP/IP packet, and sends it off to your computer’s default gateway router, with its destination marked as Port 80 at the webserver’s IP address. The packet passes through your computer’s network adapter (or modem, if you’re on dial-up), to the gateway, which starts routing it across the Internet.

Once the packet gets where it’s going, the information makes its way back through the layers in reverse order. The network card on the webserver computer receives the request, strips out the relevant information, and passes it to the webserver program. This program inspects it and finds that it understands the request, gets the information requested from local memory or the hard drive, and creates a reply packet (or many reply packets) containing the requested information. These go back through the same process to your computer, where the information is processed into a web page.

The amazing part is that all of this (usually) happens in a few milliseconds’ time.

The HTTP protocol is one of those things that don’t always get a lot of attention. It does its thing, so most folks don’t think about it. I recently came across a post on Slashdot that suggested taking a look at the HTTP headers being sent out by the Slashdot web server. It suggested running the following command in Linux:


echo -e “HEAD / HTTP/1.1\nHost: slashdot.org\n\n” | netcat slashdot.org 80 

Being an inquisitive sort (and not seeing anything really harmful-looking in the command), I decided to try it out. As it turns out, the Linux box I have available doesn’t have netcat installed, so I decided to take the lazy way out and try telnetting to Port 80 using Windows. ( C:\> telnet slashdot.org 80 )

Amazingly, it actually worked. Here’s what I sent:


HEAD / HTTP/1.1 <enter>
Host: slashdot.org <enter>
<enter>

…and I received:


HTTP/1.1 200 OK
Server: Apache/1.3.41 (Unix) mod_perl/1.31-rc4
SLASH_LOG_DATA: shtml
X-Powered-By: Slash 2.005001
X-Bender: The laws of science be a harsh mistress.
X-XRDS-Location: http://slashdot.org/slashdot.xrds
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/html; charset=iso-8859-1
Content-Length: 99945
Date: Sat, 12 Sep 2009 16:14:08 GMT
X-Varnish: 1558400757 1558400652
Age: 6
Connection: keep-alive 

First of all, I just impersonated a Web browser — and you can, too! How cool is that? You open a Telnet connection to the webserver’s Port 80, send a properly-formatted request for information, and it replies.

The other interesting part — a little wasteful but still cool — is the “X-Bender:” header. Slashdot’s webservers apparently insert interesting little quotes from Bender and other staples of geek culture into their HTTP headers. (If the Internet is the Information Superhighway, think of this sort of thing like the “wash me” and “I may be slow, but I’m ahead of you” messages you sometimes see written in the dust on the back of eighteen-wheelers. The Muggles shopping at the Wal-Marts where the trucks deliver their goods will never see these messages, but they’re there if you know where to look. Geeks being geeks, the dark steam tunnels of Internet protocols are no doubt full of such things.)

Finally, a bit of philosophy. The reason it all works — and the reason that it’s so open and free — is exactly this sort of modularity. Why is playing with the HTTP protocol cool? Not because it’s particularly interesting, but because, out there, there’s a document that shows the publicly-available, agreed-upon protocol for requesting information from a webserver — and if this protocol is followed, it works no matter who wrote the webserver, what country it’s in, what language the programmers used (or speak), or what information is on the server. HTTP, in turn, rests on other, similar layers, with other, similar protocols. With the proper (freely available) documentation in hand, you could build your own network from scratch — blowing glass to make vacuum tubes and designing your own computer, and connect it to a cable or DSL modem in your house. If you did everything right, it would work. No magic, no proprietary “sorry, you don’t get to see how this bit works,” no smoke-and-mirrors. If you use an open-source OS like Linux, you can (in theory) literally understand every movement of every bit, all the way through the whole process. It’s both a great way to learn about technology — and a great way to show just how cool freedom is.

We need to make sure it always stays this way.

Posted in Coding, System Administration | 1 Comment

Really for the birds

Now I know what my friend Leon is talking about when he complains about slow Internet speeds in Durban, South Africa.

A company in South Africa, annoyed with the slow ISP connectivity available, decided to stage a race between their ISP and a carrier pigeon, to see which was a faster method of transferring 4GB of call center data logs to their branch office 80km away.

The pigeon won.

Not only that, but it blew their ISP away. In the two hours, six minutes, 57 seconds it took to complete the data transfer (one hour eight minutes flight time, plus uploading, downloading, etc), their ISP (Telkom) managed to transfer only 4% of the data. For this particular application, that’s 1/25 of a pigeonbaud, I suppose.

As Andrew S. Tanenbaum famously noted, “Never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.”

…Or, apparently, of a homing pigeon carrying an SD card. And this one wasn’t even highly motivated!

Posted in Humor, System Administration | Leave a comment

For the birds…?

Not understanding what all the fuss is about, but being both curious and bored, I decided to sign up for Twitter. Apparently I’m now officially a “Twitterer.”

Now, to figure out what to tweet about. (Never mind figuring out whether anyone cares or not — I have two followers already. Welcome, whoever you are. Good to see there’s someone out there more bored than I am, I guess!)

Philosophically, I don’t “get” all of this emphasis on social networks. My take on ubiquitous connectivity and IT automation is that one of the really cool benefits of all of this is the extent to which it *reduces* necessary interpersonal contact. For instance, online banking and e-commerce.

However, I may be a curmudgeon and “born old” according to several friends — but no technologist should dismiss technologies out of hand without a good reason. Twitter seems harmless enough, providing one is careful about the information tweeted — so why not give it a try?

Right now, though, I’m blogging about tweeting — and have connected Twitter to this blog via the RSS feed. There’s a whole lot of connectivity there — but it’s all self-referential. Is there a point? I guess I’ll see.

Posted in Digital Citizenship | 1 Comment

ROMfoolery

“I spy, with my little eye, a ROM address beginning with the sequence 0001010000011001…”

I’ve recently been playing with DS18B20 One-Wire digital temperature sensors (from Sparkfun — big surprise there). They’re fun little devices — accurate and cheap. They’re also insanely easy to wire up, having only three leads (they look just like 2N2222 transistors).

When Maxim says “one wire,” they mean it (not counting ground); you can even power it using the data line if you’re careful about timings and provide a strong pull-up when needed. Developing microcontroller code to drive them is nontrivial, though (various layers include bit timings, commands and ROM codes etc), but once it’s working, they’re very reliable.

Temperature A-to-D conversion takes up to 750ms, but you can issue a broadcast command to get all devices on the line to start a conversion at once, then read the results back at your leisure.

Here’s the first interesting part.

With a one-wire interface, timing and coordination of reliable two-way communications gets tricky. There’s no synchronization line — and from the description in the datasheet, the timing accuracy of these sensors isn’t all that wonderful, anyway. The scheme that Maxim worked out was that a short low pulse represents a one, and a longer low pulse represents a zero. A really long (more than 480 microseconds long) pulse resets the bus altogether.

But wait, there’s more.

The interface is specified so that multiple slave devices (I.E. multiple sensors) can share the bus. This takes not only coordination, but implementing the bus with an open-drain configuration (in other words, you use a fairly weak resistor to put 5V on the bus — and devices are only allowed to short the bus to ground, not pull it high.) This keeps communication collisions between devices on the bus from causing short circuits and burning up output transistors — but it also complicates timings and the basic communications protocol.

Now for the really interesting part.

Each sensor has a unique 64-bit serial number, which you need to know in order to interface with it. It’s not marked on the package (too small) or in the literature you get when you order the part (that would make too much sense), so Maxim provides a “Search ROM” feature, which uses a bizarre take on Manchester coding to send the address back. Two bits are read out at a time for each bit position in the 64-digit ROM code. 01 means the bit is a 0; 10 means it’s a 1; 00 means a conflict (someone on the bus sent a 1 and someone else — maybe a lot of someone elses — sent a 0); and 11 means that nobody is listening (check the circuit?). By going through bit by bit (with a lot of backtracking, if addressing a lot of these on one line), you can eventually determine the ROM codes for all devices on the line. It’s very Byzantine — but when you think about it, that’s really a result of the one-wire interface.

Here’s an example of how it would work with simpler devices that only had 4-bit ROM codes.

Suppose you had three devices on the bus, with ROM codes 0110, 1110, and 0101.

The least-significant bit is sent first; this comes back in two-bit Manchester coding as an “00.” (I.E. there’s at least one of each variety.)

The master (microcontroller) makes a decision at this point, and sends a one or zero. Any devices which match this bit in the first position keep listening; all others go idle and wait for a bus reset. In this case, we’ll default to zeros first. The master notes a conflict here, and sends a zero.

Sensor 0101 reads the zero and goes idle. Sensors 0110 and 1110 read the zero and continue, since it matches the least-significant bit in their ROM code.

The master then continues with reading the second bit. This comes back as a “10” — apparently all remaining devices agree that there is a “1” here. The master records a “1” and continues.

The master reads a third bit, which comes back as another 10. Another “1” is recorded and transmitted.

The master reads a fourth bit, which reads “00”. (Another conflict.) The master sends a zero; device 1110 goes idle, while 0110 is made active (having passed all the way through its ROM code). The master records 0110 as the ROM code of one of the devices on the bus — and records 1110, since it can deduce that; this being the last bit, that’s the only possibility.

The master then resets the bus, starts the ROM search process again, but sends a “1” this time when it reaches the conflict in the first bit. Device 0101 remains active this time while 1110 and 0110 go idle. The master then continues with the process; since 0101 is the only device left on the bus, no more conflicts occur.

Think of this process, expanded to 64 bits, and you have an idea of the situation. And not only that — you then have to figure out which sensor is which, if they are in different positions!

The amazing part is, once the code for this is written, it’s all over in a few milliseconds, and the ROM codes appear on the LCD…

Posted in Digital, PIC Microcontrollers | 1 Comment