As of Linux commit 5d39580f68e6, SO_ATTACH_FILTER requires
CAP_NET_ADMIN for TCP sockets.
Skip in tests if we don't have it, and update Netstack to require it
too.
Linux's do_tcp_getsockopt() clamps the user-supplied buflen via
len = min_t(unsigned int, len, sizeof(int)) and copies that many
bytes of the integer value, so a sub-int (or zero-length) buffer
returns a truncated result rather than EINVAL. gVisor instead
rejects any outLen < 4 with EINVAL, which breaks real callers:
python-trio probes TCP_NODELAY with buflen=1 to detect its
availability and fails with OSError(EINVAL).
Route all 12 integer TCP options (TCP_NODELAY, TCP_CORK,
TCP_QUICKACK, TCP_MAXSEG, TCP_KEEPIDLE, TCP_KEEPINTVL,
TCP_KEEPCNT, TCP_USER_TIMEOUT, TCP_LINGER2, TCP_DEFER_ACCEPT,
TCP_SYNCNT, TCP_WINDOW_CLAMP) through a shared helper that
truncates the value to outLen bytes, matching Linux. outLen == 0
is a valid (zero-byte) read and must not be rejected.
Reference: net/ipv4/tcp.c:do_tcp_getsockopt()
Signed-off-by: Tan Yifeng <[email protected]>
The UDP endpoint only accepted PMTUDiscoveryDont and the TCP endpoint
rejected PMTUDiscoveryProbe, causing QUIC libraries (quic-go) to fail
when setting IP_PMTUDISC_DO or IP_PMTUDISC_PROBE on UDP sockets.
Accept all valid PMTUD strategies (DONT/WANT/DO/PROBE) for both UDP
and TCP, since gVisor does not implement ICMP-based PMTU feedback,
`PROBE` and `DO` are functionally equivalent — both set DF but neither
updates a cached route PMTU.
Test: UdpSocketTest.SetPMTUD, TcpSocketTest.SetPMTUD
Signed-off-by: Tan Yifeng <[email protected]>
This change fixes two issues in the TcpSCMPriority test that caused failures on
Linux:
1. Fix Control Buffer Size Calculation: The control buffer size was previously
calculated using nested macros: CMSG_SPACE(sizeof(timeval) +
CMSG_SPACE(sizeof(int))). This is incorrect as it fails to account for the
total alignment padding required for multiple distinct messages. The
calculation is updated to the correct additive form:
CMSG_SPACE(sizeof(timeval)) + CMSG_SPACE(sizeof(int)).
2. Fix Race Condition in SO_TIMESTAMP Generation: Previously,
setsockopt(SO_TIMESTAMP) was called after the client had already written
data to the socket. Because the kernel generates timestamps at the moment of
packet ingress, the data in the receive queue did not have timestamps
attached, resulting in a missing control message. This caused the test to
fail assertions expecting SO_TIMESTAMP to be the first message received. The
socket options are now enabled before the client writes data.
Together, these fixes ensure the control messages are correctly generated and
received without truncation.
PiperOrigin-RevId: 858770547
The timeout was set to 10 seconds, which is too long. Should be sufficient to
timeout in 3 seconds to ensure read()/send() is blocked.
These tests have multiple variants too. Together, they take too long to run.
PiperOrigin-RevId: 687411356
Give the Netstack additional time to reject incoming connections for which
there are no listening sockets. This prevents flakes in test environments with
CPU contention, where the Netstack may be descheduled for multiple seconds.
PiperOrigin-RevId: 623165285
TCP sender is initialized only in established state, check if sender is
available before disabling the TCP_CORK timer.
Reported-by: [email protected]
PiperOrigin-RevId: 616879762
Has the same effect as Linux commit 34dfde4ad87b ("tcp: Return user_mss for
TCP_MAXSEG in CLOSE/LISTEN state if user_mss set").
Updated test to accept both values (default and user set) so test works on
newer and older kernels.
PiperOrigin-RevId: 563844012
The utility function used to interpret `EWOULDBLOCK` of a `write` call as
buffers being filled at both the receiver and the sender. This is not a valid
assumption even on Linux because it is possible that the test fills the sender
buffer faster than the socket is able to transfer the bytes, in that case,
EWOULDBLOCK will be observed even before the receiver side has a full buffer.
The fix to this is to inspect the buffer size at the receiver side, and discard
any error before the receiver buffer is full. Then we can use EWOULDBLOCK to
indicate the sender buffer is full.
PiperOrigin-RevId: 538202277
Regression test for b/280313827. We also mark the specific still-failing S/R
tests with DisableSave so that tcp_socket_test can be run with S/R tests.
Tested with the pre-cl/528876775 code to ensure it failed.
PiperOrigin-RevId: 530747608
A few minor fixes. The biggest change is that the blocking implementation needs
to wait on POLLHUP and POLLERR events, in addition to readable/writable events.
We also need to track shutdown state in the socket.
PiperOrigin-RevId: 529816115
Change the parameters for filling the send buffer:
1. Use a larger buffer to account for the fact that the real send buffer is
larger than the size we set.
2. Use a longer sleep duration to reduce the chance of flakes.
PiperOrigin-RevId: 528562364
The blocking implementation needs to wait on POLLHUP and POLLERR events, in
addition to readable/writable events. That fixed at least one test.
There's still two unresolved issues in the tests, but we can enable the rest
of the suite while we figure out those two.
PiperOrigin-RevId: 525849045
When testing TCP behavior with connections that don't succeed, don't use
port 0 in the target address. Instead, reserve a port by binding but not
listening with a different socket, and try connecting to that.
Fixes#8749
PiperOrigin-RevId: 519776842
Add a test that asserts that POLLIN is set on a TCP listener when a
new connection is available to be accepted and is unset after the
connection is actually accepted.
PiperOrigin-RevId: 518075095
A few fixes in here:
* Linux does not transition the state of a non-blocking socket to SS_CONNECTED
when the connect happens asynchronously. Instead, it leaves the state as
SS_CONNECTING (seems like a Linux bug, but OK). This can introduce weird
behavior for subsequent connect() calls. gVisor now forces the state to
update to SS_CONNECTED by calling connect() twice.
* Socket shutdown events are slightly different between gVisor and linux. We
already assert different behavior between the two environments, and now we
also have to check for gVisor+hostinet instead of just gvisor.
* Handle send/recv timeouts, which fixes blocking for read()/write() syscalls.
* Handle cases like MSG_PEEK where the senderAddress is not returned.
* Pass through some more socketopts, and allow them in the syscall filters.
Something is still wrong with shutdown() and poll() calls, so those tests are
temporarily disabled. I'm looking at those next.
This also fixes a number of other syscall test suites, so those are enabled as
well.
PiperOrigin-RevId: 508397317
When checking how much data is left in the receive queue, retry to allow
time for packets to propagate and the system to push data into the
socket's receive queue.
PiperOrigin-RevId: 500257746
The existing implementation uses raw pointers, which means:
- Threads are joined at the end of each loop, and the test therefore doesn't
actually exercise the syscalls in parallel.
- The later call to `Join` is undefined behavior.
PiperOrigin-RevId: 478845631
Use the FileDescriptor helper class to manage the lifetime of file descriptors
held as TcpSocketTest members. This will help prevent leaks if some part of the
test setup fails.
Also rename `first_fd` and `second_fd` to be a) more meaningfully named and
b) conform to Google C++ naming conventions for class members.
Updates #8028
PiperOrigin-RevId: 478527874
This doesn't appear to be covered by any existing tests. Check that the peer
address for a connected TCP socket matches the local address for the
corresponding accepted socket, and vice-versa.
Fixes#8020
PiperOrigin-RevId: 477186443
Netstack has an internal StateBound state that a listening socket
transitions to before it actually transitions to StateListen. This
state is not handled by the dispatcher because normally a socket in
StateBound is never registered with the demuxer. But in case of listen
there is a small race window where the socket is in StateBound after
registering with dispatcher but before it transitions to Listen.
An incoming segment that hits the window causes the dispatcher to
panic. This change makes it so that we transition to Listen before
registering and if registration fails we now transition to a CLOSED
state same as what linux does.
See: https://github.com/google/gvisor/issues/7428Fixes#7428
PiperOrigin-RevId: 443489134
Before this change, when a new connection was created after receiving
an ACK that matched a SYN-cookie, it was always delivered asynchronously
to the accept queue. There was a chance that the listening endpoint
would process a SYN from another client before the delivery happened,
and the listening endpoint would not know yet that the queue was about
to be full, once the delivery happened.
Now, when an ACK matching a SYN-cookie is received, the new endpoint is
created and moved to the accept queue synchronously, while holding the
accept lock.
Fixes#6545
PiperOrigin-RevId: 398107254