summaryrefslogtreecommitdiffhomepage
path: root/test/syscalls
diff options
context:
space:
mode:
authorTony Gong <gongt@google.com>2020-07-07 16:13:21 -0700
committergVisor bot <gvisor-bot@google.com>2020-07-07 16:14:49 -0700
commit76c7bc51b7b02c4ba83c0a064c3629bb5ee91340 (patch)
tree48c1525ebbb54fc47a3cbd46c4e3efee957300aa /test/syscalls
parent7e4d2d63eef3f643222181b3a227bfc7ebe44db2 (diff)
Set IPv4 ID on all non-atomic datagrams
RFC 6864 imposes various restrictions on the uniqueness of the IPv4 Identification field for non-atomic datagrams, defined as an IP datagram that either can be fragmented (DF=0) or is already a fragment (MF=1 or positive fragment offset). In order to be compliant, the ID field is assigned for all non-atomic datagrams. Add a TCP unit test that induces retransmissions and checks that the IPv4 ID field is unique every time. Add basic handling of the IP_MTU_DISCOVER socket option so that the option can be used to disable PMTU discovery, effectively setting DF=0. Attempting to set the sockopt to anything other than disabled will fail because PMTU discovery is currently not implemented, and the default behavior matches that of disabled. PiperOrigin-RevId: 320081842
Diffstat (limited to 'test/syscalls')
-rw-r--r--test/syscalls/linux/raw_socket_hdrincl.cc51
1 files changed, 3 insertions, 48 deletions
diff --git a/test/syscalls/linux/raw_socket_hdrincl.cc b/test/syscalls/linux/raw_socket_hdrincl.cc
index 0a27506aa..16cfc1d75 100644
--- a/test/syscalls/linux/raw_socket_hdrincl.cc
+++ b/test/syscalls/linux/raw_socket_hdrincl.cc
@@ -273,52 +273,7 @@ TEST_F(RawHDRINCL, SendAndReceive) {
// The network stack should have set the source address.
EXPECT_EQ(src.sin_family, AF_INET);
EXPECT_EQ(absl::gbswap_32(src.sin_addr.s_addr), INADDR_LOOPBACK);
- // The packet ID should be 0, as the packet is less than 68 bytes.
- struct iphdr iphdr = {};
- memcpy(&iphdr, recv_buf, sizeof(iphdr));
- EXPECT_EQ(iphdr.id, 0);
-}
-
-// Send and receive a packet with nonzero IP ID.
-TEST_F(RawHDRINCL, SendAndReceiveNonzeroID) {
- int port = 40000;
- if (!IsRunningOnGvisor()) {
- port = static_cast<short>(ASSERT_NO_ERRNO_AND_VALUE(
- PortAvailable(0, AddressFamily::kIpv4, SocketType::kUdp, false)));
- }
-
- // IPPROTO_RAW sockets are write-only. We'll have to open another socket to
- // read what we write.
- FileDescriptor udp_sock =
- ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_INET, SOCK_RAW, IPPROTO_UDP));
-
- // Construct a packet with an IP header, UDP header, and payload. Make the
- // payload large enough to force an IP ID to be assigned.
- constexpr char kPayload[128] = {};
- char packet[sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(kPayload)];
- ASSERT_TRUE(
- FillPacket(packet, sizeof(packet), port, kPayload, sizeof(kPayload)));
-
- socklen_t addrlen = sizeof(addr_);
- ASSERT_NO_FATAL_FAILURE(sendto(socket_, &packet, sizeof(packet), 0,
- reinterpret_cast<struct sockaddr*>(&addr_),
- addrlen));
-
- // Receive the payload.
- char recv_buf[sizeof(packet)];
- struct sockaddr_in src;
- socklen_t src_size = sizeof(src);
- ASSERT_THAT(recvfrom(udp_sock.get(), recv_buf, sizeof(recv_buf), 0,
- reinterpret_cast<struct sockaddr*>(&src), &src_size),
- SyscallSucceedsWithValue(sizeof(packet)));
- EXPECT_EQ(
- memcmp(kPayload, recv_buf + sizeof(struct iphdr) + sizeof(struct udphdr),
- sizeof(kPayload)),
- 0);
- // The network stack should have set the source address.
- EXPECT_EQ(src.sin_family, AF_INET);
- EXPECT_EQ(absl::gbswap_32(src.sin_addr.s_addr), INADDR_LOOPBACK);
- // The packet ID should not be 0, as the packet was more than 68 bytes.
+ // The packet ID should not be 0, as the packet has DF=0.
struct iphdr* iphdr = reinterpret_cast<struct iphdr*>(recv_buf);
EXPECT_NE(iphdr->id, 0);
}
@@ -368,10 +323,10 @@ TEST_F(RawHDRINCL, SendAndReceiveDifferentAddress) {
// The network stack should have set the source address.
EXPECT_EQ(src.sin_family, AF_INET);
EXPECT_EQ(absl::gbswap_32(src.sin_addr.s_addr), INADDR_LOOPBACK);
- // The packet ID should be 0, as the packet is less than 68 bytes.
+ // The packet ID should not be 0, as the packet has DF=0.
struct iphdr recv_iphdr = {};
memcpy(&recv_iphdr, recv_buf, sizeof(recv_iphdr));
- EXPECT_EQ(recv_iphdr.id, 0);
+ EXPECT_NE(recv_iphdr.id, 0);
// The destination address should be localhost, not the bad IP we set
// initially.
EXPECT_EQ(absl::gbswap_32(recv_iphdr.daddr), INADDR_LOOPBACK);