mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Fix reconnect of UDP socket.
The reconnect for UDP sockets was failing because we were not removing the old registration before attempting to register again. Fix this issue by removing the old registration and then registering the endpoint. Updates #8998 PiperOrigin-RevId: 582007411
This commit is contained in:
committed by
gVisor bot
parent
8c52800156
commit
8cfc543a3f
@@ -679,11 +679,6 @@ func (e *endpoint) Connect(addr tcpip.FullAddress) tcpip.Error {
|
||||
|
||||
oldPortFlags := e.boundPortFlags
|
||||
|
||||
nextID, btd, err := e.registerWithStack(netProtos, nextID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove the old registration.
|
||||
if e.localPort != 0 {
|
||||
previousID.LocalPort = e.localPort
|
||||
@@ -691,6 +686,11 @@ func (e *endpoint) Connect(addr tcpip.FullAddress) tcpip.Error {
|
||||
e.stack.UnregisterTransportEndpoint(e.effectiveNetProtos, ProtocolNumber, previousID, e, oldPortFlags, e.boundBindToDevice)
|
||||
}
|
||||
|
||||
nextID, btd, err := e.registerWithStack(netProtos, nextID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e.localPort = nextID.LocalPort
|
||||
e.remotePort = nextID.RemotePort
|
||||
e.boundBindToDevice = btd
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <netinet/icmp6.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
|
||||
#include <cerrno>
|
||||
#include <ctime>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -2447,6 +2448,40 @@ TEST_P(UdpSocketTest, ReadShutdownOnBoundSocket) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(UdpSocketTest, ReconnectDoesNotClearReadShutdown) {
|
||||
// TODO(gvisor.dev/issue/1202): Reconnecting the UDP socket after shutdown
|
||||
// fails on hostinet.
|
||||
SKIP_IF(IsRunningWithHostinet());
|
||||
ASSERT_NO_ERRNO(BindLoopback());
|
||||
ASSERT_THAT(connect(sock_.get(), bind_addr_, addrlen_), SyscallSucceeds());
|
||||
ASSERT_THAT(shutdown(sock_.get(), SHUT_RD), SyscallSucceeds());
|
||||
|
||||
char received[512];
|
||||
EXPECT_THAT(recv(sock_.get(), received, sizeof(received), 0),
|
||||
SyscallSucceedsWithValue(0));
|
||||
|
||||
EXPECT_THAT(connect(sock_.get(), bind_addr_, addrlen_), SyscallSucceeds());
|
||||
EXPECT_THAT(recv(sock_.get(), received, sizeof(received), 0),
|
||||
SyscallSucceedsWithValue(0));
|
||||
}
|
||||
|
||||
TEST_P(UdpSocketTest, ReconnectDoesNotClearWriteShutdown) {
|
||||
// TODO(gvisor.dev/issue/1202): Reconnecting the UDP socket after shutdown
|
||||
// fails on hostinet.
|
||||
SKIP_IF(IsRunningWithHostinet());
|
||||
ASSERT_NO_ERRNO(BindLoopback());
|
||||
ASSERT_THAT(connect(sock_.get(), bind_addr_, addrlen_), SyscallSucceeds());
|
||||
|
||||
const char buf = 'A';
|
||||
ASSERT_THAT(send(sock_.get(), &buf, 1, 0), SyscallSucceeds());
|
||||
|
||||
ASSERT_THAT(shutdown(sock_.get(), SHUT_WR), SyscallSucceeds());
|
||||
EXPECT_THAT(send(sock_.get(), &buf, 1, 0), SyscallFailsWithErrno(EPIPE));
|
||||
|
||||
EXPECT_THAT(connect(sock_.get(), bind_addr_, addrlen_), SyscallSucceeds());
|
||||
EXPECT_THAT(send(sock_.get(), &buf, 1, 0), SyscallFailsWithErrno(EPIPE));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(AllInetTests, UdpSocketControlMessagesTest,
|
||||
::testing::Values(AddressFamily::kIpv4,
|
||||
AddressFamily::kIpv6,
|
||||
|
||||
Reference in New Issue
Block a user