Change UDP socket ReceiveMessage to perform peek first and then create a packet of the correct size.

Change-Id: Ia16538141d821744afcf616f615b43768d6af645
Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/1702868
Commit-Queue: Max Yakimakha <yakimakha@chromium.org>
Reviewed-by: mark a. foltz <mfoltz@chromium.org>
Reviewed-by: Ryan Keane <rwkeane@google.com>
diff --git a/platform/api/udp_packet.h b/platform/api/udp_packet.h
new file mode 100644
index 0000000..a05bdb7
--- /dev/null
+++ b/platform/api/udp_packet.h
@@ -0,0 +1,47 @@
+// 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 PLATFORM_API_UDP_PACKET_H_
+#define PLATFORM_API_UDP_PACKET_H_
+
+#include <vector>
+
+#include "platform/api/logging.h"
+#include "platform/base/ip_address.h"
+
+namespace openscreen {
+namespace platform {
+
+class UdpSocket;
+
+static constexpr size_t kUdpMaxPacketSize = 1 << 16;
+
+class UdpPacket : public std::vector<uint8_t> {
+ public:
+  explicit UdpPacket(size_t size) : std::vector<uint8_t>(size) {
+    OSP_DCHECK(size <= kUdpMaxPacketSize);
+  };
+  UdpPacket() : UdpPacket(0){};
+
+  const IPEndpoint& source() const { return source_; }
+  void set_source(IPEndpoint endpoint) { source_ = std::move(endpoint); }
+
+  const IPEndpoint& destination() const { return destination_; }
+  void set_destination(IPEndpoint endpoint) {
+    destination_ = std::move(endpoint);
+  }
+
+  UdpSocket* socket() const { return socket_; }
+  void set_socket(UdpSocket* socket) { socket_ = socket; }
+
+ private:
+  IPEndpoint source_ = {};
+  IPEndpoint destination_ = {};
+  UdpSocket* socket_ = nullptr;
+};
+
+}  // namespace platform
+}  // namespace openscreen
+
+#endif  // PLATFORM_API_UDP_PACKET_H_
\ No newline at end of file
diff --git a/platform/api/udp_read_callback.h b/platform/api/udp_read_callback.h
index f69efd4..4a68575 100644
--- a/platform/api/udp_read_callback.h
+++ b/platform/api/udp_read_callback.h
@@ -5,39 +5,20 @@
 #ifndef PLATFORM_API_UDP_READ_CALLBACK_H_
 #define PLATFORM_API_UDP_READ_CALLBACK_H_
 
-#include <array>
-#include <cstdint>
-#include <memory>
-
-#include "platform/base/ip_address.h"
+#include "platform/api/udp_packet.h"
 
 namespace openscreen {
 namespace platform {
 
 class NetworkRunner;
-class UdpSocket;
-
-static constexpr int kUdpMaxPacketSize = 1 << 16;
 
 class UdpReadCallback {
  public:
-  struct Packet : std::array<uint8_t, kUdpMaxPacketSize> {
-    Packet() = default;
-    ~Packet() = default;
-
-    IPEndpoint source;
-    IPEndpoint original_destination;
-    ssize_t length;
-    // TODO(btolsch): When this gets to implementation, make sure the callback
-    // is never called with a |socket| that could have been destroyed (e.g.
-    // between queueing the read data and running the task).
-    UdpSocket* socket;
-  };
-
   virtual ~UdpReadCallback() = default;
-
-  virtual void OnRead(std::unique_ptr<Packet> data,
-                      NetworkRunner* network_runner) = 0;
+  // TODO(btolsch): When this gets to implementation, make sure the callback
+  // is never called with a |packet| from a socket that could have been
+  // destroyed (e.g. between queueing the read data and running the task).
+  virtual void OnRead(UdpPacket packet, NetworkRunner* network_runner) = 0;
 };
 
 }  // namespace platform
diff --git a/platform/api/udp_socket.h b/platform/api/udp_socket.h
index 7ac9035..e060d41 100644
--- a/platform/api/udp_socket.h
+++ b/platform/api/udp_socket.h
@@ -10,6 +10,7 @@
 #include <memory>
 
 #include "platform/api/network_interface.h"
+#include "platform/api/udp_read_callback.h"
 #include "platform/base/error.h"
 #include "platform/base/ip_address.h"
 #include "platform/base/macros.h"
@@ -79,13 +80,8 @@
   // received. Note that a non-Error return value of 0 is a valid result,
   // indicating an empty message has been received. Also note that
   // Error::Code::kAgain might be returned if there is no message currently
-  // ready for receive, which can be expected during normal operation. |src| and
-  // |original_destination| are optional output arguments that provide the
-  // source of the message and its intended destination, respectively.
-  virtual ErrorOr<size_t> ReceiveMessage(void* data,
-                                         size_t length,
-                                         IPEndpoint* src,
-                                         IPEndpoint* original_destination) = 0;
+  // ready for receive, which can be expected during normal operation.
+  virtual ErrorOr<UdpPacket> ReceiveMessage() = 0;
 
   // Sends a message and returns the number of bytes sent, on success.
   // Error::Code::kAgain might be returned to indicate the operation would