mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
{S,G}etsockopt for TCP_KEEPCNT option.
TCP_KEEPCNT is used to set the maximum keepalive probes to be sent before dropping the connection. WANT_LGTM=jchacon PiperOrigin-RevId: 315758094
This commit is contained in:
committed by
gVisor bot
parent
a5a4f80487
commit
4b9652d63b
@@ -57,4 +57,5 @@ const (
|
||||
const (
|
||||
MAX_TCP_KEEPIDLE = 32767
|
||||
MAX_TCP_KEEPINTVL = 32767
|
||||
MAX_TCP_KEEPCNT = 127
|
||||
)
|
||||
|
||||
@@ -1246,6 +1246,18 @@ func getSockOptTCP(t *kernel.Task, ep commonEndpoint, name, outLen int) (interfa
|
||||
|
||||
return int32(time.Duration(v) / time.Second), nil
|
||||
|
||||
case linux.TCP_KEEPCNT:
|
||||
if outLen < sizeOfInt32 {
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
v, err := ep.GetSockOptInt(tcpip.KeepaliveCountOption)
|
||||
if err != nil {
|
||||
return nil, syserr.TranslateNetstackError(err)
|
||||
}
|
||||
|
||||
return int32(v), nil
|
||||
|
||||
case linux.TCP_USER_TIMEOUT:
|
||||
if outLen < sizeOfInt32 {
|
||||
return nil, syserr.ErrInvalidArgument
|
||||
@@ -1786,6 +1798,17 @@ func setSockOptTCP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *
|
||||
}
|
||||
return syserr.TranslateNetstackError(ep.SetSockOpt(tcpip.KeepaliveIntervalOption(time.Second * time.Duration(v))))
|
||||
|
||||
case linux.TCP_KEEPCNT:
|
||||
if len(optVal) < sizeOfInt32 {
|
||||
return syserr.ErrInvalidArgument
|
||||
}
|
||||
|
||||
v := usermem.ByteOrder.Uint32(optVal)
|
||||
if v < 1 || v > linux.MAX_TCP_KEEPCNT {
|
||||
return syserr.ErrInvalidArgument
|
||||
}
|
||||
return syserr.TranslateNetstackError(ep.SetSockOptInt(tcpip.KeepaliveCountOption, int(v)))
|
||||
|
||||
case linux.TCP_USER_TIMEOUT:
|
||||
if len(optVal) < sizeOfInt32 {
|
||||
return syserr.ErrInvalidArgument
|
||||
@@ -2115,30 +2138,20 @@ func emitUnimplementedEventTCP(t *kernel.Task, name int) {
|
||||
switch name {
|
||||
case linux.TCP_CONGESTION,
|
||||
linux.TCP_CORK,
|
||||
linux.TCP_DEFER_ACCEPT,
|
||||
linux.TCP_FASTOPEN,
|
||||
linux.TCP_FASTOPEN_CONNECT,
|
||||
linux.TCP_FASTOPEN_KEY,
|
||||
linux.TCP_FASTOPEN_NO_COOKIE,
|
||||
linux.TCP_KEEPCNT,
|
||||
linux.TCP_KEEPIDLE,
|
||||
linux.TCP_KEEPINTVL,
|
||||
linux.TCP_LINGER2,
|
||||
linux.TCP_MAXSEG,
|
||||
linux.TCP_QUEUE_SEQ,
|
||||
linux.TCP_QUICKACK,
|
||||
linux.TCP_REPAIR,
|
||||
linux.TCP_REPAIR_QUEUE,
|
||||
linux.TCP_REPAIR_WINDOW,
|
||||
linux.TCP_SAVED_SYN,
|
||||
linux.TCP_SAVE_SYN,
|
||||
linux.TCP_SYNCNT,
|
||||
linux.TCP_THIN_DUPACK,
|
||||
linux.TCP_THIN_LINEAR_TIMEOUTS,
|
||||
linux.TCP_TIMESTAMP,
|
||||
linux.TCP_ULP,
|
||||
linux.TCP_USER_TIMEOUT,
|
||||
linux.TCP_WINDOW_CLAMP:
|
||||
linux.TCP_ULP:
|
||||
|
||||
t.Kernel().EmitUnimplementedEvent(t)
|
||||
}
|
||||
|
||||
@@ -524,6 +524,7 @@ TEST_P(TCPSocketPairTest, SetTCPKeepintvlZero) {
|
||||
// Copied from include/net/tcp.h.
|
||||
constexpr int MAX_TCP_KEEPIDLE = 32767;
|
||||
constexpr int MAX_TCP_KEEPINTVL = 32767;
|
||||
constexpr int MAX_TCP_KEEPCNT = 127;
|
||||
|
||||
TEST_P(TCPSocketPairTest, SetTCPKeepidleAboveMax) {
|
||||
auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
|
||||
@@ -575,6 +576,78 @@ TEST_P(TCPSocketPairTest, SetTCPKeepintvlToMax) {
|
||||
EXPECT_EQ(get, MAX_TCP_KEEPINTVL);
|
||||
}
|
||||
|
||||
TEST_P(TCPSocketPairTest, TCPKeepcountDefault) {
|
||||
auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
|
||||
|
||||
int get = -1;
|
||||
socklen_t get_len = sizeof(get);
|
||||
EXPECT_THAT(
|
||||
getsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPCNT, &get, &get_len),
|
||||
SyscallSucceedsWithValue(0));
|
||||
EXPECT_EQ(get_len, sizeof(get));
|
||||
EXPECT_EQ(get, 9); // 9 keepalive probes.
|
||||
}
|
||||
|
||||
TEST_P(TCPSocketPairTest, SetTCPKeepcountZero) {
|
||||
auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
|
||||
|
||||
constexpr int kZero = 0;
|
||||
EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPCNT, &kZero,
|
||||
sizeof(kZero)),
|
||||
SyscallFailsWithErrno(EINVAL));
|
||||
}
|
||||
|
||||
TEST_P(TCPSocketPairTest, SetTCPKeepcountAboveMax) {
|
||||
auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
|
||||
|
||||
constexpr int kAboveMax = MAX_TCP_KEEPCNT + 1;
|
||||
EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPCNT,
|
||||
&kAboveMax, sizeof(kAboveMax)),
|
||||
SyscallFailsWithErrno(EINVAL));
|
||||
}
|
||||
|
||||
TEST_P(TCPSocketPairTest, SetTCPKeepcountToMax) {
|
||||
auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
|
||||
|
||||
EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPCNT,
|
||||
&MAX_TCP_KEEPCNT, sizeof(MAX_TCP_KEEPCNT)),
|
||||
SyscallSucceedsWithValue(0));
|
||||
|
||||
int get = -1;
|
||||
socklen_t get_len = sizeof(get);
|
||||
EXPECT_THAT(
|
||||
getsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPCNT, &get, &get_len),
|
||||
SyscallSucceedsWithValue(0));
|
||||
EXPECT_EQ(get_len, sizeof(get));
|
||||
EXPECT_EQ(get, MAX_TCP_KEEPCNT);
|
||||
}
|
||||
|
||||
TEST_P(TCPSocketPairTest, SetTCPKeepcountToOne) {
|
||||
auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
|
||||
|
||||
int keepaliveCount = 1;
|
||||
EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPCNT,
|
||||
&keepaliveCount, sizeof(keepaliveCount)),
|
||||
SyscallSucceedsWithValue(0));
|
||||
|
||||
int get = -1;
|
||||
socklen_t get_len = sizeof(get);
|
||||
EXPECT_THAT(
|
||||
getsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPCNT, &get, &get_len),
|
||||
SyscallSucceedsWithValue(0));
|
||||
EXPECT_EQ(get_len, sizeof(get));
|
||||
EXPECT_EQ(get, keepaliveCount);
|
||||
}
|
||||
|
||||
TEST_P(TCPSocketPairTest, SetTCPKeepcountToNegative) {
|
||||
auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
|
||||
|
||||
int keepaliveCount = -5;
|
||||
EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_TCP, TCP_KEEPCNT,
|
||||
&keepaliveCount, sizeof(keepaliveCount)),
|
||||
SyscallFailsWithErrno(EINVAL));
|
||||
}
|
||||
|
||||
TEST_P(TCPSocketPairTest, SetOOBInline) {
|
||||
auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user