gfe-relnote: Add QuicUdpSocketApi, a de-platformized version of QuicSocketUtils, and use it in some non-production code. No behavior change, not protected.

This is the first step to kill quic_socket_utils.(h|cc).

Chromium merge notes:
1) The platform impl function, GetGooglePacketHeadersFromControlMessageImpl, can simply return false.
2) Please add quic/core/quic_udp_socket* to "epoll_quic_tools" in BUILD.gn: http://shortn/_zpf4caOcsa

PiperOrigin-RevId: 289439832
Change-Id: I3bf2d1f21314bcfb2c3a72f74fab25a22d49d49d
diff --git a/quic/core/quic_udp_socket.h b/quic/core/quic_udp_socket.h
new file mode 100644
index 0000000..86972d1
--- /dev/null
+++ b/quic/core/quic_udp_socket.h
@@ -0,0 +1,225 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
+#define QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_
+
+#include <cstddef>
+#include <cstdint>
+
+#include <type_traits>
+
+#include "net/third_party/quiche/src/quic/core/quic_types.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
+
+namespace quic {
+
+#if defined(_WIN32)
+using QuicUdpSocketFd = SOCKET;
+const QuicUdpSocketFd kQuicInvalidSocketFd = INVALID_SOCKET;
+#else
+using QuicUdpSocketFd = int;
+const QuicUdpSocketFd kQuicInvalidSocketFd = -1;
+#endif
+
+enum class QuicUdpPacketInfoBit : uint8_t {
+  DROPPED_PACKETS = 0,   // Read
+  V4_SELF_IP,            // Read
+  V6_SELF_IP,            // Read
+  PEER_ADDRESS,          // Read & Write
+  RECV_TIMESTAMP,        // Read
+  TTL,                   // Read & Write
+  GOOGLE_PACKET_HEADER,  // Read
+  NUM_BITS,
+};
+static_assert(static_cast<size_t>(QuicUdpPacketInfoBit::NUM_BITS) <=
+                  BitMask64::NumBits(),
+              "BitMask64 not wide enough to hold all bits.");
+
+// BufferSpan points to an unowned buffer, copying this structure only copies
+// the pointer and length, not the buffer itself.
+struct QUIC_EXPORT_PRIVATE BufferSpan {
+  BufferSpan(char* buffer, size_t buffer_len)
+      : buffer(buffer), buffer_len(buffer_len) {}
+
+  BufferSpan() = default;
+  BufferSpan(const BufferSpan& other) = default;
+  BufferSpan& operator=(const BufferSpan& other) = default;
+
+  char* buffer = nullptr;
+  size_t buffer_len = 0;
+};
+
+// QuicUdpPacketInfo contains per-packet information used for sending and
+// receiving.
+class QUIC_EXPORT_PRIVATE QuicUdpPacketInfo {
+ public:
+  BitMask64 bitmask() const { return bitmask_; }
+
+  bool HasValue(QuicUdpPacketInfoBit bit) const { return bitmask_.IsSet(bit); }
+
+  QuicPacketCount dropped_packets() const {
+    DCHECK(HasValue(QuicUdpPacketInfoBit::DROPPED_PACKETS));
+    return dropped_packets_;
+  }
+
+  void SetDroppedPackets(QuicPacketCount dropped_packets) {
+    dropped_packets_ = dropped_packets;
+    bitmask_.Set(QuicUdpPacketInfoBit::DROPPED_PACKETS);
+  }
+
+  const QuicIpAddress& self_v4_ip() const {
+    DCHECK(HasValue(QuicUdpPacketInfoBit::V4_SELF_IP));
+    return self_v4_ip_;
+  }
+
+  void SetSelfV4Ip(QuicIpAddress self_v4_ip) {
+    self_v4_ip_ = self_v4_ip;
+    bitmask_.Set(QuicUdpPacketInfoBit::V4_SELF_IP);
+  }
+
+  const QuicIpAddress& self_v6_ip() const {
+    DCHECK(HasValue(QuicUdpPacketInfoBit::V6_SELF_IP));
+    return self_v6_ip_;
+  }
+
+  void SetSelfV6Ip(QuicIpAddress self_v6_ip) {
+    self_v6_ip_ = self_v6_ip;
+    bitmask_.Set(QuicUdpPacketInfoBit::V6_SELF_IP);
+  }
+
+  void SetSelfIp(QuicIpAddress self_ip) {
+    if (self_ip.IsIPv4()) {
+      SetSelfV4Ip(self_ip);
+    } else {
+      SetSelfV6Ip(self_ip);
+    }
+  }
+
+  const QuicSocketAddress& peer_address() const {
+    DCHECK(HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS));
+    return peer_address_;
+  }
+
+  void SetPeerAddress(QuicSocketAddress peer_address) {
+    peer_address_ = peer_address;
+    bitmask_.Set(QuicUdpPacketInfoBit::PEER_ADDRESS);
+  }
+
+  QuicWallTime receive_timestamp() const {
+    DCHECK(HasValue(QuicUdpPacketInfoBit::RECV_TIMESTAMP));
+    return receive_timestamp_;
+  }
+
+  void SetReceiveTimestamp(QuicWallTime receive_timestamp) {
+    receive_timestamp_ = receive_timestamp;
+    bitmask_.Set(QuicUdpPacketInfoBit::RECV_TIMESTAMP);
+  }
+
+  int ttl() const {
+    DCHECK(HasValue(QuicUdpPacketInfoBit::TTL));
+    return ttl_;
+  }
+
+  void SetTtl(int ttl) {
+    ttl_ = ttl;
+    bitmask_.Set(QuicUdpPacketInfoBit::TTL);
+  }
+
+  void SetGooglePacketHeaders(BufferSpan google_packet_headers) {
+    google_packet_headers_ = google_packet_headers;
+    bitmask_.Set(QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER);
+  }
+
+ private:
+  BitMask64 bitmask_;
+  QuicPacketCount dropped_packets_;
+  QuicIpAddress self_v4_ip_;
+  QuicIpAddress self_v6_ip_;
+  QuicSocketAddress peer_address_;
+  QuicWallTime receive_timestamp_ = QuicWallTime::Zero();
+  int ttl_;
+  BufferSpan google_packet_headers_;
+};
+
+// QuicUdpSocketApi provides a minimal set of apis for sending and receiving
+// udp packets. The low level udp socket apis differ between kernels and kernel
+// versions, the goal of QuicUdpSocketApi is to hide such differences.
+// We use non-static functions because it is easier to be mocked in tests when
+// needed.
+class QUIC_EXPORT_PRIVATE QuicUdpSocketApi {
+ public:
+  // Creates a non-blocking udp socket, sets the receive/send buffer and enable
+  // receiving of self ip addresses on read.
+  // Return kQuicInvalidSocketFd if failed.
+  QuicUdpSocketFd Create(int address_family,
+                         int receive_buffer_size,
+                         int send_buffer_size);
+
+  // Closes |fd|. No-op if |fd| equals to kQuicInvalidSocketFd.
+  void Destroy(QuicUdpSocketFd fd);
+
+  // Bind |fd| to |address|. If |address|'s port number is 0, kernel will choose
+  // a random port to bind to. Caller can use QuicSocketAddress::FromSocket(fd)
+  // to get the bound random port.
+  bool Bind(QuicUdpSocketFd fd, QuicSocketAddress address);
+
+  // Enable receiving of various per-packet information. Return true if the
+  // corresponding information can be received on read.
+  bool EnableDroppedPacketCount(QuicUdpSocketFd fd);
+  bool EnableReceiveTimestamp(QuicUdpSocketFd fd);
+  bool EnableReceiveTtlForV4(QuicUdpSocketFd fd);
+  bool EnableReceiveTtlForV6(QuicUdpSocketFd fd);
+
+  // Wait for |fd| to become readable, up to |timeout|.
+  // Return true if |fd| is readable upon return.
+  bool WaitUntilReadable(QuicUdpSocketFd fd, QuicTime::Delta timeout);
+
+  struct QUIC_EXPORT_PRIVATE ReadPacketResult {
+    bool ok = false;
+    QuicUdpPacketInfo packet_info;
+    BufferSpan packet_buffer;
+    BufferSpan control_buffer;
+  };
+  // Read a packet from |fd|:
+  // packet_info_interested: Bitmask indicating what information caller wants to
+  //                         receive into |result->packet_info|.
+  // result->packet_info:    Received per packet information.
+  // result->packet_buffer:  The packet buffer, to be filled with packet data.
+  // result->control_buffer: The control buffer, used by ReadPacket internally.
+  //                         It is recommended to be at least 512 bytes.
+  // result->ok:             True iff a packet is successfully received.
+  void ReadPacket(QuicUdpSocketFd fd,
+                  BitMask64 packet_info_interested,
+                  ReadPacketResult* result);
+
+  using ReadPacketResults = std::vector<ReadPacketResult>;
+  // Read up to |results->size()| packets from |fd|. The meaning of each element
+  // in |*results| has been documented on top of |ReadPacket|.
+  size_t ReadMultiplePackets(QuicUdpSocketFd fd,
+                             BitMask64 packet_info_interested,
+                             ReadPacketResults* results);
+
+  // Write a packet to |fd|.
+  // packet_buffer, packet_buffer_len:  The packet buffer to write.
+  // packet_info:                       The per packet information to set.
+  WriteResult WritePacket(QuicUdpSocketFd fd,
+                          const char* packet_buffer,
+                          size_t packet_buffer_len,
+                          const QuicUdpPacketInfo& packet_info);
+
+ protected:
+  bool SetupSocket(QuicUdpSocketFd fd,
+                   int address_family,
+                   int receive_buffer_size,
+                   int send_buffer_size);
+  bool EnableReceiveSelfIpAddressForV4(QuicUdpSocketFd fd);
+  bool EnableReceiveSelfIpAddressForV6(QuicUdpSocketFd fd);
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_UDP_SOCKET_H_