github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/syscalls/linux/socket_ip_udp_generic.cc (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "test/syscalls/linux/socket_ip_udp_generic.h" 16 17 #include <errno.h> 18 #ifdef __linux__ 19 #include <linux/in6.h> 20 #endif // __linux__ 21 #include <netinet/in.h> 22 #include <netinet/tcp.h> 23 #include <poll.h> 24 #include <stdio.h> 25 #include <sys/ioctl.h> 26 #include <sys/socket.h> 27 #include <sys/types.h> 28 #include <sys/un.h> 29 30 #include "gtest/gtest.h" 31 #include "test/syscalls/linux/socket_test_util.h" 32 #include "test/util/test_util.h" 33 34 namespace gvisor { 35 namespace testing { 36 37 TEST_P(UDPSocketPairTest, MulticastTTLDefault) { 38 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 39 40 int get = -1; 41 socklen_t get_len = sizeof(get); 42 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 43 &get, &get_len), 44 SyscallSucceedsWithValue(0)); 45 EXPECT_EQ(get_len, sizeof(get)); 46 EXPECT_EQ(get, 1); 47 } 48 49 TEST_P(UDPSocketPairTest, SetUDPMulticastTTLMin) { 50 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 51 52 constexpr int kMin = 0; 53 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 54 &kMin, sizeof(kMin)), 55 SyscallSucceeds()); 56 57 int get = -1; 58 socklen_t get_len = sizeof(get); 59 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 60 &get, &get_len), 61 SyscallSucceedsWithValue(0)); 62 EXPECT_EQ(get_len, sizeof(get)); 63 EXPECT_EQ(get, kMin); 64 } 65 66 TEST_P(UDPSocketPairTest, SetUDPMulticastTTLMax) { 67 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 68 69 constexpr int kMax = 255; 70 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 71 &kMax, sizeof(kMax)), 72 SyscallSucceeds()); 73 74 int get = -1; 75 socklen_t get_len = sizeof(get); 76 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 77 &get, &get_len), 78 SyscallSucceedsWithValue(0)); 79 EXPECT_EQ(get_len, sizeof(get)); 80 EXPECT_EQ(get, kMax); 81 } 82 83 TEST_P(UDPSocketPairTest, SetUDPMulticastTTLNegativeOne) { 84 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 85 86 constexpr int kArbitrary = 6; 87 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 88 &kArbitrary, sizeof(kArbitrary)), 89 SyscallSucceeds()); 90 91 constexpr int kNegOne = -1; 92 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 93 &kNegOne, sizeof(kNegOne)), 94 SyscallSucceeds()); 95 96 int get = -1; 97 socklen_t get_len = sizeof(get); 98 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 99 &get, &get_len), 100 SyscallSucceedsWithValue(0)); 101 EXPECT_EQ(get_len, sizeof(get)); 102 EXPECT_EQ(get, 1); 103 } 104 105 TEST_P(UDPSocketPairTest, SetUDPMulticastTTLBelowMin) { 106 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 107 108 constexpr int kBelowMin = -2; 109 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 110 &kBelowMin, sizeof(kBelowMin)), 111 SyscallFailsWithErrno(EINVAL)); 112 } 113 114 TEST_P(UDPSocketPairTest, SetUDPMulticastTTLAboveMax) { 115 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 116 117 constexpr int kAboveMax = 256; 118 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 119 &kAboveMax, sizeof(kAboveMax)), 120 SyscallFailsWithErrno(EINVAL)); 121 } 122 123 TEST_P(UDPSocketPairTest, SetUDPMulticastTTLChar) { 124 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 125 126 constexpr char kArbitrary = 6; 127 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 128 &kArbitrary, sizeof(kArbitrary)), 129 SyscallSucceeds()); 130 131 int get = -1; 132 socklen_t get_len = sizeof(get); 133 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 134 &get, &get_len), 135 SyscallSucceedsWithValue(0)); 136 EXPECT_EQ(get_len, sizeof(get)); 137 EXPECT_EQ(get, kArbitrary); 138 } 139 140 TEST_P(UDPSocketPairTest, SetEmptyIPAddMembership) { 141 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 142 143 struct ip_mreqn req = {}; 144 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, 145 &req, sizeof(req)), 146 SyscallFailsWithErrno(EINVAL)); 147 } 148 149 TEST_P(UDPSocketPairTest, MulticastLoopDefault) { 150 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 151 152 int get = -1; 153 socklen_t get_len = sizeof(get); 154 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 155 &get, &get_len), 156 SyscallSucceedsWithValue(0)); 157 EXPECT_EQ(get_len, sizeof(get)); 158 EXPECT_EQ(get, kSockOptOn); 159 } 160 161 TEST_P(UDPSocketPairTest, SetMulticastLoop) { 162 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 163 164 ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 165 &kSockOptOff, sizeof(kSockOptOff)), 166 SyscallSucceeds()); 167 168 int get = -1; 169 socklen_t get_len = sizeof(get); 170 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 171 &get, &get_len), 172 SyscallSucceedsWithValue(0)); 173 EXPECT_EQ(get_len, sizeof(get)); 174 EXPECT_EQ(get, kSockOptOff); 175 176 ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 177 &kSockOptOn, sizeof(kSockOptOn)), 178 SyscallSucceeds()); 179 180 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 181 &get, &get_len), 182 SyscallSucceedsWithValue(0)); 183 EXPECT_EQ(get_len, sizeof(get)); 184 EXPECT_EQ(get, kSockOptOn); 185 } 186 187 TEST_P(UDPSocketPairTest, SetMulticastLoopChar) { 188 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 189 190 constexpr char kSockOptOnChar = kSockOptOn; 191 constexpr char kSockOptOffChar = kSockOptOff; 192 193 ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 194 &kSockOptOffChar, sizeof(kSockOptOffChar)), 195 SyscallSucceeds()); 196 197 int get = -1; 198 socklen_t get_len = sizeof(get); 199 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 200 &get, &get_len), 201 SyscallSucceedsWithValue(0)); 202 EXPECT_EQ(get_len, sizeof(get)); 203 EXPECT_EQ(get, kSockOptOff); 204 205 ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 206 &kSockOptOnChar, sizeof(kSockOptOnChar)), 207 SyscallSucceeds()); 208 209 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 210 &get, &get_len), 211 SyscallSucceedsWithValue(0)); 212 EXPECT_EQ(get_len, sizeof(get)); 213 EXPECT_EQ(get, kSockOptOn); 214 } 215 216 TEST_P(UDPSocketPairTest, ReuseAddrDefault) { 217 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 218 219 int get = -1; 220 socklen_t get_len = sizeof(get); 221 ASSERT_THAT( 222 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len), 223 SyscallSucceedsWithValue(0)); 224 EXPECT_EQ(get_len, sizeof(get)); 225 EXPECT_EQ(get, kSockOptOff); 226 } 227 228 TEST_P(UDPSocketPairTest, SetReuseAddr) { 229 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 230 231 ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, 232 &kSockOptOn, sizeof(kSockOptOn)), 233 SyscallSucceeds()); 234 235 int get = -1; 236 socklen_t get_len = sizeof(get); 237 ASSERT_THAT( 238 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len), 239 SyscallSucceedsWithValue(0)); 240 EXPECT_EQ(get_len, sizeof(get)); 241 EXPECT_EQ(get, kSockOptOn); 242 243 ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, 244 &kSockOptOff, sizeof(kSockOptOff)), 245 SyscallSucceeds()); 246 247 ASSERT_THAT( 248 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len), 249 SyscallSucceedsWithValue(0)); 250 EXPECT_EQ(get_len, sizeof(get)); 251 EXPECT_EQ(get, kSockOptOff); 252 } 253 254 TEST_P(UDPSocketPairTest, ReusePortDefault) { 255 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 256 257 int get = -1; 258 socklen_t get_len = sizeof(get); 259 ASSERT_THAT( 260 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len), 261 SyscallSucceedsWithValue(0)); 262 EXPECT_EQ(get_len, sizeof(get)); 263 EXPECT_EQ(get, kSockOptOff); 264 } 265 266 TEST_P(UDPSocketPairTest, SetReusePort) { 267 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 268 269 ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, 270 &kSockOptOn, sizeof(kSockOptOn)), 271 SyscallSucceeds()); 272 273 int get = -1; 274 socklen_t get_len = sizeof(get); 275 ASSERT_THAT( 276 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len), 277 SyscallSucceedsWithValue(0)); 278 EXPECT_EQ(get_len, sizeof(get)); 279 EXPECT_EQ(get, kSockOptOn); 280 281 ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, 282 &kSockOptOff, sizeof(kSockOptOff)), 283 SyscallSucceeds()); 284 285 ASSERT_THAT( 286 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len), 287 SyscallSucceedsWithValue(0)); 288 EXPECT_EQ(get_len, sizeof(get)); 289 EXPECT_EQ(get, kSockOptOff); 290 } 291 292 TEST_P(UDPSocketPairTest, SetReuseAddrReusePort) { 293 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 294 295 ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, 296 &kSockOptOn, sizeof(kSockOptOn)), 297 SyscallSucceeds()); 298 299 ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, 300 &kSockOptOn, sizeof(kSockOptOn)), 301 SyscallSucceeds()); 302 303 int get = -1; 304 socklen_t get_len = sizeof(get); 305 ASSERT_THAT( 306 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len), 307 SyscallSucceedsWithValue(0)); 308 EXPECT_EQ(get_len, sizeof(get)); 309 EXPECT_EQ(get, kSockOptOn); 310 311 ASSERT_THAT( 312 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len), 313 SyscallSucceedsWithValue(0)); 314 EXPECT_EQ(get_len, sizeof(get)); 315 EXPECT_EQ(get, kSockOptOn); 316 } 317 318 // Test getsockopt for a socket which is not set with IP_PKTINFO option. 319 TEST_P(UDPSocketPairTest, IPPKTINFODefault) { 320 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 321 322 int get = -1; 323 socklen_t get_len = sizeof(get); 324 325 ASSERT_THAT( 326 getsockopt(sockets->first_fd(), SOL_IP, IP_PKTINFO, &get, &get_len), 327 SyscallSucceedsWithValue(0)); 328 EXPECT_EQ(get_len, sizeof(get)); 329 EXPECT_EQ(get, kSockOptOff); 330 } 331 332 // Test setsockopt and getsockopt for a socket with IP_PKTINFO option. 333 TEST_P(UDPSocketPairTest, SetAndGetIPPKTINFO) { 334 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 335 336 int level = SOL_IP; 337 int type = IP_PKTINFO; 338 339 // Check getsockopt before IP_PKTINFO is set. 340 int get = -1; 341 socklen_t get_len = sizeof(get); 342 343 ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOn, 344 sizeof(kSockOptOn)), 345 SyscallSucceedsWithValue(0)); 346 347 ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len), 348 SyscallSucceedsWithValue(0)); 349 EXPECT_EQ(get, kSockOptOn); 350 EXPECT_EQ(get_len, sizeof(get)); 351 352 ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOff, 353 sizeof(kSockOptOff)), 354 SyscallSucceedsWithValue(0)); 355 356 ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len), 357 SyscallSucceedsWithValue(0)); 358 EXPECT_EQ(get, kSockOptOff); 359 EXPECT_EQ(get_len, sizeof(get)); 360 } 361 362 // Test getsockopt for a socket which is not set with IP_RECVORIGDSTADDR option. 363 TEST_P(UDPSocketPairTest, ReceiveOrigDstAddrDefault) { 364 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 365 366 int get = -1; 367 socklen_t get_len = sizeof(get); 368 int level = SOL_IP; 369 int type = IP_RECVORIGDSTADDR; 370 if (sockets->first_addr()->sa_family == AF_INET6) { 371 level = SOL_IPV6; 372 type = IPV6_RECVORIGDSTADDR; 373 } 374 ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len), 375 SyscallSucceedsWithValue(0)); 376 EXPECT_EQ(get_len, sizeof(get)); 377 EXPECT_EQ(get, kSockOptOff); 378 } 379 380 // Test setsockopt and getsockopt for a socket with IP_RECVORIGDSTADDR option. 381 TEST_P(UDPSocketPairTest, SetAndGetReceiveOrigDstAddr) { 382 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 383 384 int level = SOL_IP; 385 int type = IP_RECVORIGDSTADDR; 386 if (sockets->first_addr()->sa_family == AF_INET6) { 387 level = SOL_IPV6; 388 type = IPV6_RECVORIGDSTADDR; 389 } 390 391 // Check getsockopt before IP_PKTINFO is set. 392 int get = -1; 393 socklen_t get_len = sizeof(get); 394 395 ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOn, 396 sizeof(kSockOptOn)), 397 SyscallSucceedsWithValue(0)); 398 399 ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len), 400 SyscallSucceedsWithValue(0)); 401 EXPECT_EQ(get, kSockOptOn); 402 EXPECT_EQ(get_len, sizeof(get)); 403 404 ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOff, 405 sizeof(kSockOptOff)), 406 SyscallSucceedsWithValue(0)); 407 408 ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len), 409 SyscallSucceedsWithValue(0)); 410 EXPECT_EQ(get, kSockOptOff); 411 EXPECT_EQ(get_len, sizeof(get)); 412 } 413 414 // Holds TOS or TClass information for IPv4 or IPv6 respectively. 415 struct RecvTosOption { 416 int level; 417 int option; 418 }; 419 420 RecvTosOption GetRecvTosOption(int domain) { 421 TEST_CHECK(domain == AF_INET || domain == AF_INET6); 422 RecvTosOption opt; 423 switch (domain) { 424 case AF_INET: 425 opt.level = IPPROTO_IP; 426 opt.option = IP_RECVTOS; 427 break; 428 case AF_INET6: 429 opt.level = IPPROTO_IPV6; 430 opt.option = IPV6_RECVTCLASS; 431 break; 432 } 433 return opt; 434 } 435 436 // Ensure that Receiving TOS or TCLASS is off by default. 437 TEST_P(UDPSocketPairTest, RecvTosDefault) { 438 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 439 RecvTosOption t = GetRecvTosOption(GetParam().domain); 440 int get = -1; 441 socklen_t get_len = sizeof(get); 442 ASSERT_THAT( 443 getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len), 444 SyscallSucceedsWithValue(0)); 445 EXPECT_EQ(get_len, sizeof(get)); 446 EXPECT_EQ(get, kSockOptOff); 447 } 448 449 // Test that setting and getting IP_RECVTOS or IPV6_RECVTCLASS works as 450 // expected. 451 TEST_P(UDPSocketPairTest, SetRecvTos) { 452 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 453 RecvTosOption t = GetRecvTosOption(GetParam().domain); 454 455 ASSERT_THAT(setsockopt(sockets->first_fd(), t.level, t.option, &kSockOptOff, 456 sizeof(kSockOptOff)), 457 SyscallSucceeds()); 458 459 int get = -1; 460 socklen_t get_len = sizeof(get); 461 ASSERT_THAT( 462 getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len), 463 SyscallSucceedsWithValue(0)); 464 EXPECT_EQ(get_len, sizeof(get)); 465 EXPECT_EQ(get, kSockOptOff); 466 467 ASSERT_THAT(setsockopt(sockets->first_fd(), t.level, t.option, &kSockOptOn, 468 sizeof(kSockOptOn)), 469 SyscallSucceeds()); 470 471 ASSERT_THAT( 472 getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len), 473 SyscallSucceedsWithValue(0)); 474 EXPECT_EQ(get_len, sizeof(get)); 475 EXPECT_EQ(get, kSockOptOn); 476 } 477 478 // Test that any socket (including IPv6 only) accepts the IPv4 TOS option: this 479 // mirrors behavior in linux. 480 TEST_P(UDPSocketPairTest, TOSRecvMismatch) { 481 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 482 RecvTosOption t = GetRecvTosOption(AF_INET); 483 int get = -1; 484 socklen_t get_len = sizeof(get); 485 486 ASSERT_THAT( 487 getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len), 488 SyscallSucceedsWithValue(0)); 489 } 490 491 // Test that an IPv4 socket does not support the IPv6 TClass option. 492 TEST_P(UDPSocketPairTest, TClassRecvMismatch) { 493 // This should only test AF_INET6 sockets for the mismatch behavior. 494 SKIP_IF(GetParam().domain != AF_INET6); 495 // IPV6_RECVTCLASS is only valid for SOCK_DGRAM and SOCK_RAW. 496 SKIP_IF((GetParam().type != SOCK_DGRAM) | (GetParam().type != SOCK_RAW)); 497 498 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 499 500 int get = -1; 501 socklen_t get_len = sizeof(get); 502 503 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IPV6, IPV6_RECVTCLASS, 504 &get, &get_len), 505 SyscallFailsWithErrno(EOPNOTSUPP)); 506 } 507 508 // Test the SO_LINGER option can be set/get on udp socket. 509 TEST_P(UDPSocketPairTest, SetAndGetSocketLinger) { 510 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 511 int level = SOL_SOCKET; 512 int type = SO_LINGER; 513 514 struct linger sl; 515 sl.l_onoff = 1; 516 sl.l_linger = 5; 517 ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &sl, sizeof(sl)), 518 SyscallSucceedsWithValue(0)); 519 520 struct linger got_linger = {}; 521 socklen_t length = sizeof(sl); 522 ASSERT_THAT( 523 getsockopt(sockets->first_fd(), level, type, &got_linger, &length), 524 SyscallSucceedsWithValue(0)); 525 526 ASSERT_EQ(length, sizeof(got_linger)); 527 EXPECT_EQ(0, memcmp(&sl, &got_linger, length)); 528 } 529 530 // Test getsockopt for SO_ACCEPTCONN on udp socket. 531 TEST_P(UDPSocketPairTest, GetSocketAcceptConn) { 532 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 533 534 int got = -1; 535 socklen_t length = sizeof(got); 536 ASSERT_THAT( 537 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_ACCEPTCONN, &got, &length), 538 SyscallSucceedsWithValue(0)); 539 540 ASSERT_EQ(length, sizeof(got)); 541 EXPECT_EQ(got, 0); 542 } 543 544 } // namespace testing 545 } // namespace gvisor