If no client is attached, discard outgoing frames and report them as
sent. Without this we will get an EBADF in either writev() (pasta) or
sendmsg() (passt). That's basically harmless, but a bit ugly.
Explicitly catching this case results in behaviour that's probably a
bit clearer to debug if we hit it.
There are several different approaches we can take here. Here's some
reasoning as David explained:
* Don't listen() until the tap connection is ready
- It's not clear that the host rejecting the connection is better
than the host accepting, then the connection stalling until the
guest is ready.
- Would require substantial rework because we currently listen() as
we parse the command line and don't store the information we'd need
to do it later.
* Don't accept() until the tap connection is ready
- To the peer, will behave basically the same as this patch - the
host will complete the TCP handshake, then the connection will stall
until the guest is ready.
- More work to implement, because essentially every sock-side handler
has to check fd_tap and abort early
* Drop packets in tap_send_frames(), but return 0
- To the peer, would behave basically the same
- Would make the TCP code do a bunch of busy work attempting to
resend, probably to no avail
- Handling of errors returned by tap_send_frames() is on the basis
that it's probably a transient fault (buffer full) and we want to
resend very soon. That approach doesn't make sense for a missing
guest.
Suggested-by: David Gibson