AddrInfo now has ref()/unref() and keeps a global socket->refcount map
(since actual AddrInfo instances come and go.) When the
count drops to 0, the existing CloseSocket() method is called. This
seems to fix a bunch of race conditions that had a socket being closed
and reused while old code was still expecting to write to the device
attached to the socket the first time (along with lots of calls to close()
already-closed sockets, attempts to write() to closed sockets, etc.)
timestamp set when it's opened. Older copies with the same socket can
be tested against the cannonical copy maintained by tpool and sending
avoided when the timestamp shows the endpoint has likely changed.
Change tpool's list of sockets to a map for faster lookup, and get rid
of similar structure in udpqueue.
queue the packets for processing. Add ids so they can be tracked in
the logs. In addition to making tcp and udp packet processing more
similar this fixes the case where a read is delayed until after the
client has closed the connection (and so returns an error.)