This should resolve the spurious ping timeouts we've had on low powered
boxes. Those errors are the result of us requiring a timely Pong
response to our Pings. However this is unnecessarily strict - as long as
we've received *anything* recently, we know the other peer is alive. So
the new mechanism removes the Pong message entirely and separates the
ping check into two routines:
- One that makes sure to send ping periodically, if nothing else has
been sent. This guarantees a message sent every 45-90 seconds.
- One that checks how long it was since we last received a message. If
it's longer than 300 seconds, we trigger an ErrTimeout.
So we're guaranteed to detect a connection failure in 300 + 300/2
seconds (due to how often the check runs) and we may detect it much
sooner if we get an actual error on the ping write (a connection reset
or so).
This is more sluggish than before but I think that's an OK price to pay
for making it actually work out of the box.
This removes the configurability of it, as the timeout on one side is
dependent on the send interval on the other side. Do we still need it
configurable?
We allocate a []byte to read the message into, so if the header says the
messages is several gigabytes large we may run into trouble. In reality,
a message should never be that large so we impose a limit.
Integers are for numbers, enabling arithmetic like subtractions and for
loops without getting shot in the foot. Unsigneds are for bitfields.
- "int" for numbers that will always be laughably smaller than four
billion, and where we don't care about the serialization format.
- "int32" for numbers that will always be laughably smaller than four
billion, and will be serialized to four bytes.
- "int64" for numbers that may approach four billion or will be
serialized to eight bytes.
- "uint32" and "uint64" for bitfields, depending on required number of
bits and serialization format. Likewise "uint8" and "uint16", although
rare in this project since they don't exist in XDR.
- "int8", "int16" and plain "uint" are almost never useful.
This change makes sure that things work smoothly when "we" are a newer
version than our peer and have more fields in our messages than they do.
Missing fields will be left at zero/nil.
(The other side will ignore our extra fields, for the same effect.)