gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/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/errqueue.h> 20 #include <linux/in6.h> 21 #endif // __linux__ 22 #include <netinet/in.h> 23 #include <netinet/tcp.h> 24 #include <poll.h> 25 #include <stdio.h> 26 #include <sys/ioctl.h> 27 #include <sys/socket.h> 28 #include <sys/types.h> 29 #include <sys/un.h> 30 31 #include "gtest/gtest.h" 32 #include "test/util/socket_util.h" 33 #include "test/util/test_util.h" 34 35 namespace gvisor { 36 namespace testing { 37 38 TEST_P(UDPSocketPairTest, MulticastTTLDefault) { 39 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 40 41 int get = -1; 42 socklen_t get_len = sizeof(get); 43 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 44 &get, &get_len), 45 SyscallSucceedsWithValue(0)); 46 EXPECT_EQ(get_len, sizeof(get)); 47 EXPECT_EQ(get, 1); 48 } 49 50 TEST_P(UDPSocketPairTest, SetUDPMulticastTTLMin) { 51 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 52 53 constexpr int kMin = 0; 54 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 55 &kMin, sizeof(kMin)), 56 SyscallSucceeds()); 57 58 int get = -1; 59 socklen_t get_len = sizeof(get); 60 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 61 &get, &get_len), 62 SyscallSucceedsWithValue(0)); 63 EXPECT_EQ(get_len, sizeof(get)); 64 EXPECT_EQ(get, kMin); 65 } 66 67 TEST_P(UDPSocketPairTest, SetUDPMulticastTTLMax) { 68 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 69 70 constexpr int kMax = 255; 71 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 72 &kMax, sizeof(kMax)), 73 SyscallSucceeds()); 74 75 int get = -1; 76 socklen_t get_len = sizeof(get); 77 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 78 &get, &get_len), 79 SyscallSucceedsWithValue(0)); 80 EXPECT_EQ(get_len, sizeof(get)); 81 EXPECT_EQ(get, kMax); 82 } 83 84 TEST_P(UDPSocketPairTest, SetUDPMulticastTTLNegativeOne) { 85 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 86 87 constexpr int kArbitrary = 6; 88 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 89 &kArbitrary, sizeof(kArbitrary)), 90 SyscallSucceeds()); 91 92 constexpr int kNegOne = -1; 93 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 94 &kNegOne, sizeof(kNegOne)), 95 SyscallSucceeds()); 96 97 int get = -1; 98 socklen_t get_len = sizeof(get); 99 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 100 &get, &get_len), 101 SyscallSucceedsWithValue(0)); 102 EXPECT_EQ(get_len, sizeof(get)); 103 EXPECT_EQ(get, 1); 104 } 105 106 TEST_P(UDPSocketPairTest, SetUDPMulticastTTLBelowMin) { 107 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 108 109 constexpr int kBelowMin = -2; 110 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 111 &kBelowMin, sizeof(kBelowMin)), 112 SyscallFailsWithErrno(EINVAL)); 113 } 114 115 TEST_P(UDPSocketPairTest, SetUDPMulticastTTLAboveMax) { 116 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 117 118 constexpr int kAboveMax = 256; 119 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 120 &kAboveMax, sizeof(kAboveMax)), 121 SyscallFailsWithErrno(EINVAL)); 122 } 123 124 TEST_P(UDPSocketPairTest, SetUDPMulticastTTLChar) { 125 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 126 127 constexpr char kArbitrary = 6; 128 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 129 &kArbitrary, sizeof(kArbitrary)), 130 SyscallSucceeds()); 131 132 int get = -1; 133 socklen_t get_len = sizeof(get); 134 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_TTL, 135 &get, &get_len), 136 SyscallSucceedsWithValue(0)); 137 EXPECT_EQ(get_len, sizeof(get)); 138 EXPECT_EQ(get, kArbitrary); 139 } 140 141 TEST_P(UDPSocketPairTest, SetEmptyIPAddMembership) { 142 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 143 144 struct ip_mreqn req = {}; 145 EXPECT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_ADD_MEMBERSHIP, 146 &req, sizeof(req)), 147 SyscallFailsWithErrno(EINVAL)); 148 } 149 150 TEST_P(UDPSocketPairTest, MulticastLoopDefault) { 151 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 152 153 int get = -1; 154 socklen_t get_len = sizeof(get); 155 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 156 &get, &get_len), 157 SyscallSucceedsWithValue(0)); 158 EXPECT_EQ(get_len, sizeof(get)); 159 EXPECT_EQ(get, kSockOptOn); 160 } 161 162 TEST_P(UDPSocketPairTest, SetMulticastLoop) { 163 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 164 165 ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 166 &kSockOptOff, sizeof(kSockOptOff)), 167 SyscallSucceeds()); 168 169 int get = -1; 170 socklen_t get_len = sizeof(get); 171 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 172 &get, &get_len), 173 SyscallSucceedsWithValue(0)); 174 EXPECT_EQ(get_len, sizeof(get)); 175 EXPECT_EQ(get, kSockOptOff); 176 177 ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 178 &kSockOptOn, sizeof(kSockOptOn)), 179 SyscallSucceeds()); 180 181 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 182 &get, &get_len), 183 SyscallSucceedsWithValue(0)); 184 EXPECT_EQ(get_len, sizeof(get)); 185 EXPECT_EQ(get, kSockOptOn); 186 } 187 188 TEST_P(UDPSocketPairTest, SetMulticastLoopChar) { 189 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 190 191 constexpr char kSockOptOnChar = kSockOptOn; 192 constexpr char kSockOptOffChar = kSockOptOff; 193 194 ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 195 &kSockOptOffChar, sizeof(kSockOptOffChar)), 196 SyscallSucceeds()); 197 198 int get = -1; 199 socklen_t get_len = sizeof(get); 200 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 201 &get, &get_len), 202 SyscallSucceedsWithValue(0)); 203 EXPECT_EQ(get_len, sizeof(get)); 204 EXPECT_EQ(get, kSockOptOff); 205 206 ASSERT_THAT(setsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 207 &kSockOptOnChar, sizeof(kSockOptOnChar)), 208 SyscallSucceeds()); 209 210 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IP, IP_MULTICAST_LOOP, 211 &get, &get_len), 212 SyscallSucceedsWithValue(0)); 213 EXPECT_EQ(get_len, sizeof(get)); 214 EXPECT_EQ(get, kSockOptOn); 215 } 216 217 TEST_P(UDPSocketPairTest, ReuseAddrDefault) { 218 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 219 220 int get = -1; 221 socklen_t get_len = sizeof(get); 222 ASSERT_THAT( 223 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len), 224 SyscallSucceedsWithValue(0)); 225 EXPECT_EQ(get_len, sizeof(get)); 226 EXPECT_EQ(get, kSockOptOff); 227 } 228 229 TEST_P(UDPSocketPairTest, SetReuseAddr) { 230 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 231 232 ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, 233 &kSockOptOn, sizeof(kSockOptOn)), 234 SyscallSucceeds()); 235 236 int get = -1; 237 socklen_t get_len = sizeof(get); 238 ASSERT_THAT( 239 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len), 240 SyscallSucceedsWithValue(0)); 241 EXPECT_EQ(get_len, sizeof(get)); 242 EXPECT_EQ(get, kSockOptOn); 243 244 ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, 245 &kSockOptOff, sizeof(kSockOptOff)), 246 SyscallSucceeds()); 247 248 ASSERT_THAT( 249 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len), 250 SyscallSucceedsWithValue(0)); 251 EXPECT_EQ(get_len, sizeof(get)); 252 EXPECT_EQ(get, kSockOptOff); 253 } 254 255 TEST_P(UDPSocketPairTest, ReusePortDefault) { 256 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 257 258 int get = -1; 259 socklen_t get_len = sizeof(get); 260 ASSERT_THAT( 261 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len), 262 SyscallSucceedsWithValue(0)); 263 EXPECT_EQ(get_len, sizeof(get)); 264 EXPECT_EQ(get, kSockOptOff); 265 } 266 267 TEST_P(UDPSocketPairTest, SetReusePort) { 268 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 269 270 ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, 271 &kSockOptOn, sizeof(kSockOptOn)), 272 SyscallSucceeds()); 273 274 int get = -1; 275 socklen_t get_len = sizeof(get); 276 ASSERT_THAT( 277 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len), 278 SyscallSucceedsWithValue(0)); 279 EXPECT_EQ(get_len, sizeof(get)); 280 EXPECT_EQ(get, kSockOptOn); 281 282 ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, 283 &kSockOptOff, sizeof(kSockOptOff)), 284 SyscallSucceeds()); 285 286 ASSERT_THAT( 287 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len), 288 SyscallSucceedsWithValue(0)); 289 EXPECT_EQ(get_len, sizeof(get)); 290 EXPECT_EQ(get, kSockOptOff); 291 } 292 293 TEST_P(UDPSocketPairTest, SetReuseAddrReusePort) { 294 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 295 296 ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, 297 &kSockOptOn, sizeof(kSockOptOn)), 298 SyscallSucceeds()); 299 300 ASSERT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, 301 &kSockOptOn, sizeof(kSockOptOn)), 302 SyscallSucceeds()); 303 304 int get = -1; 305 socklen_t get_len = sizeof(get); 306 ASSERT_THAT( 307 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEADDR, &get, &get_len), 308 SyscallSucceedsWithValue(0)); 309 EXPECT_EQ(get_len, sizeof(get)); 310 EXPECT_EQ(get, kSockOptOn); 311 312 ASSERT_THAT( 313 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_REUSEPORT, &get, &get_len), 314 SyscallSucceedsWithValue(0)); 315 EXPECT_EQ(get_len, sizeof(get)); 316 EXPECT_EQ(get, kSockOptOn); 317 } 318 319 // Test getsockopt for a socket which is not set with IP_PKTINFO option. 320 TEST_P(UDPSocketPairTest, IPPKTINFODefault) { 321 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 322 323 int get = -1; 324 socklen_t get_len = sizeof(get); 325 326 ASSERT_THAT( 327 getsockopt(sockets->first_fd(), SOL_IP, IP_PKTINFO, &get, &get_len), 328 SyscallSucceedsWithValue(0)); 329 EXPECT_EQ(get_len, sizeof(get)); 330 EXPECT_EQ(get, kSockOptOff); 331 } 332 333 // Test setsockopt and getsockopt for a socket with IP_PKTINFO option. 334 TEST_P(UDPSocketPairTest, SetAndGetIPPKTINFO) { 335 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 336 337 int level = SOL_IP; 338 int type = IP_PKTINFO; 339 340 // Check getsockopt before IP_PKTINFO is set. 341 int get = -1; 342 socklen_t get_len = sizeof(get); 343 344 ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOn, 345 sizeof(kSockOptOn)), 346 SyscallSucceedsWithValue(0)); 347 348 ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len), 349 SyscallSucceedsWithValue(0)); 350 EXPECT_EQ(get, kSockOptOn); 351 EXPECT_EQ(get_len, sizeof(get)); 352 353 ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOff, 354 sizeof(kSockOptOff)), 355 SyscallSucceedsWithValue(0)); 356 357 ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len), 358 SyscallSucceedsWithValue(0)); 359 EXPECT_EQ(get, kSockOptOff); 360 EXPECT_EQ(get_len, sizeof(get)); 361 } 362 363 // Test getsockopt for a socket which is not set with IP_RECVORIGDSTADDR option. 364 TEST_P(UDPSocketPairTest, ReceiveOrigDstAddrDefault) { 365 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 366 367 int get = -1; 368 socklen_t get_len = sizeof(get); 369 int level = SOL_IP; 370 int type = IP_RECVORIGDSTADDR; 371 if (sockets->first_addr()->sa_family == AF_INET6) { 372 level = SOL_IPV6; 373 type = IPV6_RECVORIGDSTADDR; 374 } 375 ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len), 376 SyscallSucceedsWithValue(0)); 377 EXPECT_EQ(get_len, sizeof(get)); 378 EXPECT_EQ(get, kSockOptOff); 379 } 380 381 // Test setsockopt and getsockopt for a socket with IP_RECVORIGDSTADDR option. 382 TEST_P(UDPSocketPairTest, SetAndGetReceiveOrigDstAddr) { 383 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 384 385 int level = SOL_IP; 386 int type = IP_RECVORIGDSTADDR; 387 if (sockets->first_addr()->sa_family == AF_INET6) { 388 level = SOL_IPV6; 389 type = IPV6_RECVORIGDSTADDR; 390 } 391 392 // Check getsockopt before IP_PKTINFO is set. 393 int get = -1; 394 socklen_t get_len = sizeof(get); 395 396 ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOn, 397 sizeof(kSockOptOn)), 398 SyscallSucceedsWithValue(0)); 399 400 ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len), 401 SyscallSucceedsWithValue(0)); 402 EXPECT_EQ(get, kSockOptOn); 403 EXPECT_EQ(get_len, sizeof(get)); 404 405 ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &kSockOptOff, 406 sizeof(kSockOptOff)), 407 SyscallSucceedsWithValue(0)); 408 409 ASSERT_THAT(getsockopt(sockets->first_fd(), level, type, &get, &get_len), 410 SyscallSucceedsWithValue(0)); 411 EXPECT_EQ(get, kSockOptOff); 412 EXPECT_EQ(get_len, sizeof(get)); 413 } 414 415 // Holds TOS or TClass information for IPv4 or IPv6 respectively. 416 struct RecvTosOption { 417 int level; 418 int option; 419 }; 420 421 RecvTosOption GetRecvTosOption(int domain) { 422 TEST_CHECK(domain == AF_INET || domain == AF_INET6); 423 RecvTosOption opt; 424 switch (domain) { 425 case AF_INET: 426 opt.level = IPPROTO_IP; 427 opt.option = IP_RECVTOS; 428 break; 429 case AF_INET6: 430 opt.level = IPPROTO_IPV6; 431 opt.option = IPV6_RECVTCLASS; 432 break; 433 } 434 return opt; 435 } 436 437 // Ensure that Receiving TOS or TCLASS is off by default. 438 TEST_P(UDPSocketPairTest, RecvTosDefault) { 439 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 440 RecvTosOption t = GetRecvTosOption(GetParam().domain); 441 int get = -1; 442 socklen_t get_len = sizeof(get); 443 ASSERT_THAT( 444 getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len), 445 SyscallSucceedsWithValue(0)); 446 EXPECT_EQ(get_len, sizeof(get)); 447 EXPECT_EQ(get, kSockOptOff); 448 } 449 450 // Test that setting and getting IP_RECVTOS or IPV6_RECVTCLASS works as 451 // expected. 452 TEST_P(UDPSocketPairTest, SetRecvTos) { 453 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 454 RecvTosOption t = GetRecvTosOption(GetParam().domain); 455 456 ASSERT_THAT(setsockopt(sockets->first_fd(), t.level, t.option, &kSockOptOff, 457 sizeof(kSockOptOff)), 458 SyscallSucceeds()); 459 460 int get = -1; 461 socklen_t get_len = sizeof(get); 462 ASSERT_THAT( 463 getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len), 464 SyscallSucceedsWithValue(0)); 465 EXPECT_EQ(get_len, sizeof(get)); 466 EXPECT_EQ(get, kSockOptOff); 467 468 ASSERT_THAT(setsockopt(sockets->first_fd(), t.level, t.option, &kSockOptOn, 469 sizeof(kSockOptOn)), 470 SyscallSucceeds()); 471 472 ASSERT_THAT( 473 getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len), 474 SyscallSucceedsWithValue(0)); 475 EXPECT_EQ(get_len, sizeof(get)); 476 EXPECT_EQ(get, kSockOptOn); 477 } 478 479 // Test that any socket (including IPv6 only) accepts the IPv4 TOS option: this 480 // mirrors behavior in linux. 481 TEST_P(UDPSocketPairTest, TOSRecvMismatch) { 482 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 483 RecvTosOption t = GetRecvTosOption(AF_INET); 484 int get = -1; 485 socklen_t get_len = sizeof(get); 486 487 ASSERT_THAT( 488 getsockopt(sockets->first_fd(), t.level, t.option, &get, &get_len), 489 SyscallSucceedsWithValue(0)); 490 } 491 492 // Test that an IPv4 socket does not support the IPv6 TClass option. 493 TEST_P(UDPSocketPairTest, TClassRecvMismatch) { 494 // This should only test AF_INET6 sockets for the mismatch behavior. 495 SKIP_IF(GetParam().domain != AF_INET6); 496 // IPV6_RECVTCLASS is only valid for SOCK_DGRAM and SOCK_RAW. 497 SKIP_IF((GetParam().type != SOCK_DGRAM) || (GetParam().type != SOCK_RAW)); 498 499 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 500 501 int get = -1; 502 socklen_t get_len = sizeof(get); 503 504 ASSERT_THAT(getsockopt(sockets->first_fd(), IPPROTO_IPV6, IPV6_RECVTCLASS, 505 &get, &get_len), 506 SyscallFailsWithErrno(EOPNOTSUPP)); 507 } 508 509 // Test the SO_LINGER option can be set/get on udp socket. 510 TEST_P(UDPSocketPairTest, SetAndGetSocketLinger) { 511 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 512 int level = SOL_SOCKET; 513 int type = SO_LINGER; 514 515 struct linger sl; 516 sl.l_onoff = 1; 517 sl.l_linger = 5; 518 ASSERT_THAT(setsockopt(sockets->first_fd(), level, type, &sl, sizeof(sl)), 519 SyscallSucceedsWithValue(0)); 520 521 struct linger got_linger = {}; 522 socklen_t length = sizeof(sl); 523 ASSERT_THAT( 524 getsockopt(sockets->first_fd(), level, type, &got_linger, &length), 525 SyscallSucceedsWithValue(0)); 526 527 ASSERT_EQ(length, sizeof(got_linger)); 528 EXPECT_EQ(0, memcmp(&sl, &got_linger, length)); 529 } 530 531 // Test getsockopt for SO_ACCEPTCONN on udp socket. 532 TEST_P(UDPSocketPairTest, GetSocketAcceptConn) { 533 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 534 535 int got = -1; 536 socklen_t length = sizeof(got); 537 ASSERT_THAT( 538 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_ACCEPTCONN, &got, &length), 539 SyscallSucceedsWithValue(0)); 540 541 ASSERT_EQ(length, sizeof(got)); 542 EXPECT_EQ(got, 0); 543 } 544 545 #ifdef __linux__ 546 TEST_P(UDPSocketPairTest, PayloadTooBig) { 547 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 548 549 // Set IP_RECVERR socket option to enable error queueing. 550 int v = kSockOptOn; 551 socklen_t optlen = sizeof(v); 552 int opt_level = SOL_IP; 553 int opt_type = IP_RECVERR; 554 if (sockets->first_addr()->sa_family == AF_INET6) { 555 opt_level = SOL_IPV6; 556 opt_type = IPV6_RECVERR; 557 } 558 ASSERT_THAT(setsockopt(sockets->first_fd(), opt_level, opt_type, &v, optlen), 559 SyscallSucceeds()); 560 561 // Buffers bigger than 0xffff should receive an error. 562 const int kBufLen = 0x10000; 563 char buf[kBufLen]; 564 RandomizeBuffer(buf, sizeof(buf)); 565 566 EXPECT_THAT(send(sockets->first_fd(), buf, sizeof(buf), 0), 567 SyscallFailsWithErrno(EMSGSIZE)); 568 569 // Dequeue error using recvmsg(MSG_ERRQUEUE). Give a buffer big-enough for 570 // the original message just in case. 571 char got[kBufLen]; 572 struct iovec iov; 573 iov.iov_base = reinterpret_cast<void*>(got); 574 iov.iov_len = kBufLen; 575 576 const int addrlen_ = sockets->second_addr_size(); 577 size_t control_buf_len = CMSG_SPACE(sizeof(sock_extended_err) + addrlen_); 578 std::vector<char> control_buf(control_buf_len); 579 struct sockaddr_storage remote; 580 memset(&remote, 0, sizeof(remote)); 581 struct msghdr msg = {}; 582 msg.msg_iov = &iov; 583 msg.msg_iovlen = 1; 584 msg.msg_flags = 0; 585 msg.msg_control = control_buf.data(); 586 msg.msg_controllen = control_buf_len; 587 msg.msg_name = reinterpret_cast<void*>(&remote); 588 msg.msg_namelen = addrlen_; 589 590 struct sockaddr_storage addr; 591 optlen = sizeof(addr); 592 EXPECT_THAT(getpeername(sockets->first_fd(), AsSockAddr(&addr), &optlen), 593 SyscallSucceeds()); 594 bool ipv6 = false; 595 if (addr.ss_family == AF_INET6) { 596 auto ipv6addr = reinterpret_cast<struct sockaddr_in6*>(&addr); 597 598 // Exclude IPv4-mapped addresses. 599 uint8_t v4MappedPrefix[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 600 0x00, 0x00, 0x00, 0x00, 0xff, 0xff}; 601 ipv6 = memcmp(&ipv6addr->sin6_addr.s6_addr[0], v4MappedPrefix, 602 sizeof(v4MappedPrefix)) != 0; 603 } 604 // Native behaviour for IPv4 packets is to not report to ERRQUEUE. 605 if (!ipv6) { 606 EXPECT_THAT(recvmsg(sockets->first_fd(), &msg, MSG_ERRQUEUE), 607 SyscallFailsWithErrno(EAGAIN)); 608 return; 609 } 610 611 ASSERT_THAT(recvmsg(sockets->first_fd(), &msg, MSG_ERRQUEUE), 612 SyscallSucceedsWithValue(0)); 613 614 EXPECT_NE(msg.msg_flags & MSG_ERRQUEUE, 0); 615 EXPECT_EQ(memcmp(&remote, sockets->second_addr(), addrlen_), 0); 616 617 // Check the contents of the control message. 618 struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); 619 ASSERT_NE(cmsg, nullptr); 620 EXPECT_EQ(CMSG_NXTHDR(&msg, cmsg), nullptr); 621 EXPECT_EQ(cmsg->cmsg_level, opt_level); 622 EXPECT_EQ(cmsg->cmsg_type, opt_type); 623 EXPECT_EQ(cmsg->cmsg_len, 624 sizeof(sock_extended_err) + addrlen_ + sizeof(cmsghdr)); 625 626 // Check the contents of socket error. 627 struct sock_extended_err* sock_err = 628 reinterpret_cast<sock_extended_err*>(CMSG_DATA(cmsg)); 629 EXPECT_EQ(sock_err->ee_errno, EMSGSIZE); 630 EXPECT_EQ(sock_err->ee_origin, SO_EE_ORIGIN_LOCAL); 631 EXPECT_EQ(sock_err->ee_type, ICMP_ECHOREPLY); 632 EXPECT_EQ(sock_err->ee_code, ICMP_NET_UNREACH); 633 EXPECT_EQ(sock_err->ee_info, kBufLen); 634 EXPECT_EQ(sock_err->ee_data, 0); 635 636 // Verify that no socket error was put on the queue. 637 int err; 638 optlen = sizeof(err); 639 ASSERT_THAT( 640 getsockopt(sockets->first_fd(), SOL_SOCKET, SO_ERROR, &err, &optlen), 641 SyscallSucceeds()); 642 ASSERT_EQ(err, 0); 643 ASSERT_EQ(optlen, sizeof(err)); 644 } 645 #endif // __linux__ 646 647 } // namespace testing 648 } // namespace gvisor