diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2021-08-26 14:37:48 +0200 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2021-08-26 23:30:22 +0200 |
commit | d2272f74f72469c3d4c2368439f36bb3b348db7c (patch) | |
tree | 29422c60ae49604c790134a0fea63a4171a05452 /udp.c | |
parent | cc2ebfd5f2c73b61590a28ff7d088520ce2c1502 (diff) | |
download | passt-d2272f74f72469c3d4c2368439f36bb3b348db7c.tar passt-d2272f74f72469c3d4c2368439f36bb3b348db7c.tar.gz passt-d2272f74f72469c3d4c2368439f36bb3b348db7c.tar.bz2 passt-d2272f74f72469c3d4c2368439f36bb3b348db7c.tar.lz passt-d2272f74f72469c3d4c2368439f36bb3b348db7c.tar.xz passt-d2272f74f72469c3d4c2368439f36bb3b348db7c.tar.zst passt-d2272f74f72469c3d4c2368439f36bb3b348db7c.zip |
tcp: Proper error handling for sendmmsg() to UNIX domain socket
As data from socket is forwarded to the guest, sendmmsg() might send
fewer bytes than requested in three different ways:
- failing altogether with a negative error code -- ignore that,
we'll get an error on the UNIX domain socket later if there's
really an issue with it and reset the connection to the guest
- sending less than 'vlen' messages -- instead of assuming success
in that case and waiting for the guest to send a duplicate ACK
indicating missing data, update the sequence number according to
what was actually sent and spare some retransmissions
- somewhat unexpectedly to me, sending 'vlen' or less than 'vlen'
messages, returning up to 'vlen', with the last message being
partially sent, and no further indication of errors other than
the returned msg_len for the last partially sent message being
less than iov_len.
In this case, we would assume success and proceed as nothing
happened. However, qemu would fail to parse any further message,
having received a partial descriptor, and eventually close the
connection, logging:
serious error: oversized packet received,connection terminated.
as the length descriptor for the next message would be sourced
from the middle of the next successfully sent message, not from
its header.
Handle this by checking the msg_len returned for the last (even
partially) sent message, and force re-sending the missing bytes,
if any, with a blocking sendmsg() -- qemu must not receive
anything else than that anyway.
While at it, allow to send up to 64KiB for each message, the
previous 32KiB limit isn't actually required, and just switch to a
new message at each iteration on sending buffers, they are already
MSS-sized anyway, so the check in the loop isn't really needed.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'udp.c')
0 files changed, 0 insertions, 0 deletions