Refactor of packet handling state machine to be packet-driven

I find this a little easier to reason about, but I'm not sure if your tests still pass :P

with @akmcc