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:
Nayana Bidari
2023-11-13 10:24:31 -08:00
committed by gVisor bot
parent 8c52800156
commit 8cfc543a3f
2 changed files with 40 additions and 5 deletions
+5 -5
View File
@@ -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
+35
View File
@@ -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,