Manually marshal packets for more speed

We change the `sendPacket` function to accept a `encoding.BinaryMashaler` and implement the related `MarshalBinary` function on each packet type. This gives us great speed and allocation wins (see #16) at the expense of less readability, albeit one-time only.
return fmt.Errorf(...)