Fix SO_ACCEPTCONN option for unix sockets.

SO_ACCEPTCONN returns true for TCP sockets which are in a listening state.
Added this socket option support for unix sockets.

PiperOrigin-RevId: 577008617
This commit is contained in:
Nayana Bidari
2023-10-26 15:48:38 -07:00
committed by gVisor bot
parent b445e3ca8e
commit aa02c6fa15
5 changed files with 45 additions and 7 deletions
+2 -7
View File
@@ -1076,13 +1076,8 @@ func getSockOptSocket(t *kernel.Task, s socket.Socket, ep commonEndpoint, family
return nil, syserr.ErrInvalidArgument
}
// This option is only viable for TCP endpoints.
var v bool
if socket.IsTCP(s) {
v = tcp.EndpointState(ep.State()) == tcp.StateListen
}
vP := primitive.Int32(boolToInt32(v))
return &vP, nil
v := primitive.Int32(boolToInt32(ep.SocketOptions().GetAcceptConn()))
return &v, nil
case linux.SO_RCVLOWAT:
if outLen < sizeOfInt32 {
@@ -645,3 +645,7 @@ func (e *connectionedEndpoint) EventUnregister(we *waiter.Entry) {
fdnotifier.UpdateFD(bsFD.NotificationFD())
}
}
func (e *connectionedEndpoint) GetAcceptConn() bool {
return e.Listening()
}
+14
View File
@@ -63,6 +63,10 @@ type SocketOptionsHandler interface {
// changed. The handler notifies the writers if the send buffer size is
// increased with setsockopt(2) for TCP endpoints.
WakeupWriters()
// GetAcceptConn returns true if the socket is a TCP socket and is in
// listening state.
GetAcceptConn() bool
}
// DefaultSocketOptionsHandler is an embeddable type that implements no-op
@@ -112,6 +116,11 @@ func (*DefaultSocketOptionsHandler) OnSetReceiveBufferSize(v, oldSz int64) (newS
return v, nil
}
// GetAcceptConn implements SocketOptionsHandler.GetAcceptConn.
func (*DefaultSocketOptionsHandler) GetAcceptConn() bool {
return false
}
// StackHandler holds methods to access the stack options. These must be
// implemented by the stack.
type StackHandler interface {
@@ -742,3 +751,8 @@ func (so *SocketOptions) SetRcvlowat(rcvlowat int32) Error {
so.rcvlowat.Store(rcvlowat)
return nil
}
// GetAcceptConn gets value for SO_ACCEPTCONN option.
func (so *SocketOptions) GetAcceptConn() bool {
return so.handler.GetAcceptConn()
}
+4
View File
@@ -3325,3 +3325,7 @@ func (e *endpoint) computeTCPSendBufferSize() int64 {
return newSndBufSz
}
func (e *endpoint) GetAcceptConn() bool {
return EndpointState(e.State()) == StateListen
}
+21
View File
@@ -229,6 +229,27 @@ TEST_P(StreamUnixSocketPairTest, IncreasedSocketSendBufUnblocksWrites) {
SyscallSucceeds());
}
TEST_P(StreamUnixSocketPairTest, GetAcceptConn) {
auto bound = ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_UNIX, SOCK_STREAM, 0));
struct sockaddr_un bind_addr =
ASSERT_NO_ERRNO_AND_VALUE(UniqueUnixAddr(true, AF_UNIX));
ASSERT_THAT(bind(bound.get(), AsSockAddr(&bind_addr), sizeof(bind_addr)),
SyscallSucceeds());
int opt = 0;
socklen_t opt_len = sizeof(opt);
ASSERT_THAT(
getsockopt(bound.get(), SOL_SOCKET, SO_ACCEPTCONN, &opt, &opt_len),
SyscallSucceeds());
ASSERT_EQ(opt, 0);
ASSERT_THAT(listen(bound.get(),
/* backlog = */ 5), // NOLINT(bugprone-argument-comment)
SyscallSucceeds());
ASSERT_THAT(
getsockopt(bound.get(), SOL_SOCKET, SO_ACCEPTCONN, &opt, &opt_len),
SyscallSucceeds());
ASSERT_EQ(opt, 1);
}
INSTANTIATE_TEST_SUITE_P(
AllUnixDomainSockets, StreamUnixSocketPairTest,
::testing::ValuesIn(IncludeReversals(VecCat<SocketPairKind>(