mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
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:
committed by
gVisor bot
parent
b445e3ca8e
commit
aa02c6fa15
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -3325,3 +3325,7 @@ func (e *endpoint) computeTCPSendBufferSize() int64 {
|
||||
|
||||
return newSndBufSz
|
||||
}
|
||||
|
||||
func (e *endpoint) GetAcceptConn() bool {
|
||||
return EndpointState(e.State()) == StateListen
|
||||
}
|
||||
|
||||
@@ -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>(
|
||||
|
||||
Reference in New Issue
Block a user