Add return value to SSHSession.eof_received() for half-open channels

This commit changes the definition of SSHSession.eof_received() to
require that it return True if it wants to keep the SSHChannel
half-open, following the pattern in asyncio's Protocol class. If
True is not returned, the channel is automatically closed. If
eof_received() is not overridden, its default behavior is to close
the channel on EOF.

Prior to this change, eof_received() always left the channel half-open
until SSHSession.close() or SSHSession.abort() was called explicitly to
close it.

As part of this change, the port forwarding code has also been updated
to properly support half-open connections in either direction,
automatically closing the associated SSH channels and TCP connections
when both directions have sent an EOF.