use TCP keepalive on mogstored connection

mogstored can be idle for hours/days at a time between fsck
runs, so ensure the connection stays alive to avoid errors
and disconnects.
Mogstored/SideChannelClient: factor out validate_uri

We'll be reusing it soon
Mogstored/SideChannelClient: add command for md5

This can save bandwidth by handling all MD5 calculation on
the server side.
Mogstored/SideChannelClient: remove circular reference

This was a trivially reproducible memory leak:

  (while true; do echo md5 /path/to/small/file; done) | nc $HOST $PORT
DB changes for checksum support schema_version=15

We'll use the "checksum" table to store checksums of various
types, and allow this to be defined on a per-class basis
via the "checksumtype" column in the class table.
Mogstored/SideChannelClient: remove padding on MD5

Sticking with the defaults Digest::MD5 provides us.
For some installations, 2 bytes can add up to a lot in a
database table.
Mogstored/SideChannelClient: handle zero-byte files

We can rely on EOF to indicate the end of the file without
needing to know its size, first.
Mogstored/SideChannelClient: md5 returns -1 on open() failure

This is to be consistent with the "size" command, we no longer
shut a client down because of a missing file (possibly due to a
DELETE race).

Also, flip watch_read more consistently and try to keep it in
the md5_* family of functions.
HTTPFile: add md5 method for getting 128-bit checksum

We'll try to hit the mogstored stream port and fall back
to HTTP if the mogstored stream port does not work.
Mogstored/SideChannelClient: prevent EMFILE/EMFILE DoS from md5

This isn't meant to be /that/ secure, but do not allow MD5s
to be calculated in parallel because the client can /really/
pipeline the hell out of us and cause us to exhaust our
open descriptors.
store: add functions for binary checksum storage

Binary columns are the most space-efficient way to represent
checksum hashes.  MD5s are only 16 bytes, and our 64-byte column
can support SHA512 if we ever wanted to.

We have unit tests that pass under MySQL, Postgres, and SQLite.
t/httpfile: more tests for larger (100M) file

We need to ensure we're sane when dealing with larger files
requiring multiple reads.
increase MD5 buffers to 1 megabyte (from 16K)

This matches the buffer size used by replication, and showed a
performance increase when timing the 100M large file test in
t/40-httpfile.t

With the following patch, I was able to note a ~46 -> ~27s
time difference with both MD5 methods using this change
to increase buffer sizes.

  --- a/t/40-httpfile.t
  +++ b/t/40-httpfile.t
  @@ -125,5 +125,12 @@ $expect = $expect->digest;
   @paths = $mogc->get_paths("largefile");
   $file = MogileFS::HTTPFile->at($paths[0]);
   ok($size == $file->size, "big file size match $size");
  +use Time::HiRes qw/tv_interval gettimeofday/;
  +
  +my $t0;
  +$t0 = [gettimeofday];
   ok($file->md5_mgmt(sub {}) eq $expect, "md5_mgmt on big file");
  +print "mgmt ", tv_interval($t0), "\n";
  +$t0 = [gettimeofday];
   ok($file->md5_http(sub {}) eq $expect, "md5_http on big file");
  +print "http ", tv_interval($t0), "\n";
side_channel: switch to hexdigest for exchanging md5 checksums

Base64 requires further escaping for our tracker protocol which
gets ugly and confusing.  It's also easier to interact/verify
with existing command-line tools using hex.
add MogileFS::Checksum class

We need a place to store mappings for various checksum
types we'll support.
store: update class table with checksumtype column

This is needed to wire up checksums to classes.
replicate: optional digest support

Digest::MD5 and Digest::SHA1 both support the same API for
streaming data for the calculation, so we can validate our
content as we stream it.
class: wire up checksum support to this

Checksum usage will be decided on a per-class basis.
t/40-httpfile.t: speedup test with working clear_cache

This branch is now rebased against my latest clear_cache
which allows allows much faster metadata updates for testing.
doc: add checksums.txt for basic design/implementation notes

Helps me keep my head straight.