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