Ocean
Loading...
Searching...
No Matches
PackagedConnectionlessServer.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef FACEBOOK_NETWORK_PACKAGED_CONNECTIONLESS_SERVER_H
9#define FACEBOOK_NETWORK_PACKAGED_CONNECTIONLESS_SERVER_H
10
14
15#include "ocean/base/Callback.h"
17
18namespace Ocean
19{
20
21namespace Network
22{
23
24/**
25 * This class is the base class for all package connectionless server.
26 * The server reassembles the datagrams a PackagedConnectionlessClient produced, see PackagedSocket::packageManagmentHeaderSize() for the layout.
27 * A message is identified by (sender address, sender port, message id), and its buffer is sized from the first datagram that arrives.
28 * The receive callback is invoked once every fragment has been seen, an incomplete message is dropped after maximalMessageTime_ seconds.
29 * Because UDP neither guarantees order nor delivery, a message may never complete, and datagrams of different messages may interleave.
30 * @ingroup network
31 */
32class OCEAN_NETWORK_EXPORT PackagedConnectionlessServer :
33 virtual public PackagedConnectionlessClient,
34 virtual public Server
35{
36 public:
37
38 /**
39 * Definition of a data callback function.
40 * Parameter 0 provides the address of the sender.<br>
41 * Parameter 1 provides the port of the sender.<br>
42 * Parameter 2 provides the received buffer, which must be copied, nullptr if the message could not be delivered correctly
43 * Parameter 3 provides the size of the received buffer, in bytes; 0 if the message could not be delivered correctly
44 * Parameter 4 provides the id of the message to which the received buffer belongs
45 */
47
48 protected:
49
50 /**
51 * This class implements a message.
52 */
54 {
55 public:
56
57 /**
58 * Creates an empty data object.
59 */
60 inline MessageData() = default;
61
62 /**
63 * Copy constructor.
64 * @param messageData Message object to be copied
65 */
66 inline MessageData(const MessageData& messageData);
67
68 /**
69 * Move constructor.
70 * @param messageData Message object to be moved
71 */
72 inline MessageData(MessageData&& messageData) noexcept;
73
74 /**
75 * Creates a new message data object.
76 * @param retireTimestamp The timestamp at which this message will be retired as no further packages arrived in the meantime.
77 * @param size The size of the entire message, in bytes
78 * @param remainingPackages The number of packages in which the entire message is divided
79 */
80 inline MessageData(const Timestamp retireTimestamp, const size_t size, const unsigned int remainingPackages);
81
82 /**
83 * Returns the retire timestamp.
84 * @return Retire timestamp
85 */
86 inline Timestamp retireTimestamp() const;
87
88 /**
89 * Returns the number of remaining packages.
90 * @return Remaining packages
91 */
92 inline unsigned int remainingPackages() const;
93
94 /**
95 * Returns the size of the message buffer, in bytes.
96 * @return The number of bytes of the message buffer
97 */
98 inline size_t size() const;
99
100 /**
101 * Returns the message buffer.
102 * @return Message buffer
103 */
104 inline const uint8_t* buffer() const;
105
106 /**
107 * Returns the message buffer.
108 * @return Message buffer
109 */
110 inline uint8_t* buffer();
111
112 /**
113 * Sets or changes the retire timestamp.
114 * @param timestamp The new timestamp
115 */
116 inline void setRetireTimestamp(const Timestamp timestamp);
117
118 /**
119 * Marks one package of this message as received.
120 * A package which has already been received is ignored, so that a duplicated datagram cannot complete a message with missing payload.
121 * @param packageIndex The index of the received package, an index outside of the message is ignored
122 * @return True, if this package had not been received before
123 */
124 inline bool setPackageReceived(const unsigned int packageIndex);
125
126 /**
127 * Assign operator.
128 * @param messageData Message data object to copy
129 * @return Reference to this object
130 */
131 inline MessageData& operator=(const MessageData& messageData);
132
133 /**
134 * Move operator.
135 * @param messageData Message data object to move
136 * @return Reference to this object
137 */
138 inline MessageData& operator=(MessageData&& messageData) noexcept;
139
140 protected:
141
142 /// The timestamp at which this message will be retired as no further packages arrived in the meantime.
143 Timestamp retireTimestamp_ = Timestamp(false);
144
145 /// The number of packages which are still missing.
146 unsigned int remainingPackages_ = 0u;
147
148 /// The received state of each package of this message.
149 std::vector<uint8_t> receivedPackages_;
150
151 /// The entire buffer of the message.
153 };
154
155 /**
156 * Definition of a triple storing an address, a port and a message id.
157 */
158 class Triple
159 {
160 public:
161
162 /**
163 * Creates a new triple object.
164 * @param address The address of the object
165 * @param port The port of the object
166 * @param messageId The id of the object
167 */
168 inline Triple(const Address4& address, const Port& port, const MessageId messageId);
169
170 /**
171 * Returns the address of this object.
172 * @return The address
173 */
174 inline const Address4& address() const;
175
176 /**
177 * Returns the port of this object.
178 * @return The port
179 */
180 inline const Port& port() const;
181
182 /**
183 * Returns the message id of this object.
184 * @return The message id
185 */
186 inline MessageId messageId() const;
187
188 /**
189 * Compares two triple objects.
190 * @param triple The second triple object
191 * @return True, if the left object is lesser than the right one
192 */
193 inline bool operator<(const Triple& triple) const;
194
195 protected:
196
197 /// The address of this object.
199
200 /// The port of this object.
202
203 /// The message id of this object.
204 unsigned int messageId_ = invalidMessageId();
205 };
206
207 /**
208 * Definition of a map mapping message ids to massage data objects.
209 */
210 using MessageMap = std::map<Triple, MessageData>;
211
212 public:
213
214 /**
215 * Destructs a connectionless server object.
216 */
218
219 /**
220 * Sets the receive data callback function.
221 * @param callback the callback function to be called if a new message arrives.
222 */
223 inline void setReceiveCallback(const ReceiveCallback& callback);
224
225 protected:
226
227 /**
228 * Creates a new connectionless server object.
229 */
231
232 /**
233 * The scheduler event function.
234 * Socket::onScheduler().
235 */
236 bool onScheduler() override;
237
238 protected:
239
240 /// Data callback function called on new message arrivals.
242
243 /// The time between the first package of a large message and the decision to retire the message if still packages are missing, in seconds.
244 double maximalMessageTime_ = 5.0;
245
246 /// Intermediate buffer storing individual parts of a large message.
248
249 /// The map holding all partially received message.
251};
252
254 retireTimestamp_(messageData.retireTimestamp_),
255 remainingPackages_(messageData.remainingPackages_),
256 receivedPackages_(messageData.receivedPackages_),
257 buffer_(messageData.buffer_)
258{
259 // nothing to do here
260}
261
263 retireTimestamp_(messageData.retireTimestamp_),
264 remainingPackages_(messageData.remainingPackages_),
265 receivedPackages_(std::move(messageData.receivedPackages_)),
266 buffer_(std::move(messageData.buffer_))
267{
268 messageData.retireTimestamp_.toInvalid();
269 messageData.remainingPackages_ = 0u;
270}
271
272inline PackagedConnectionlessServer::MessageData::MessageData(const Timestamp retireTimestamp, const size_t size, const unsigned int remainingPackages) :
273 retireTimestamp_(retireTimestamp),
274 remainingPackages_(remainingPackages),
275 receivedPackages_(remainingPackages, 0u),
276 buffer_(size)
277{
278 ocean_assert(buffer_.empty() || remainingPackages_ != 0u);
279}
280
282{
283 return retireTimestamp_;
284}
285
287{
288 return remainingPackages_;
289}
290
292{
293 return buffer_.size();
294}
295
297{
298 return buffer_.data();
299}
300
302{
303 return buffer_.data();
304}
305
307{
308 retireTimestamp_ = timestamp;
309}
310
311inline bool PackagedConnectionlessServer::MessageData::setPackageReceived(const unsigned int packageIndex)
312{
313 // a peer may announce a different package count for a message which is already in flight, so the index is checked against this message
314 if (size_t(packageIndex) >= receivedPackages_.size() || receivedPackages_[packageIndex] != 0u)
315 {
316 return false;
317 }
318
319 receivedPackages_[packageIndex] = 1u;
320
321 ocean_assert(remainingPackages_ >= 1u);
322 --remainingPackages_;
323
324 return true;
325}
326
328{
329 retireTimestamp_ = messageData.retireTimestamp_;
330 remainingPackages_ = messageData.remainingPackages_;
331 receivedPackages_ = messageData.receivedPackages_;
332 buffer_ = messageData.buffer_;
333
334 return *this;
335}
336
338{
339 if (this != &messageData)
340 {
341 retireTimestamp_ = messageData.retireTimestamp_;
342 remainingPackages_ = messageData.remainingPackages_;
343 receivedPackages_ = std::move(messageData.receivedPackages_);
344 buffer_ = std::move(messageData.buffer_);
345
346 messageData.retireTimestamp_.toInvalid();
347 messageData.remainingPackages_ = 0u;
348 }
349
350 return *this;
351}
352
354 address_(address),
355 port_(port),
356 messageId_(messageId)
357{
358 // nothing to do here
359}
360
362{
363 return address_;
364}
365
367{
368 return port_;
369}
370
375
377{
378 return address_ < triple.address_ || (address_ == triple.address_ && (port_ < triple.port_ || (port_ == triple.port_ && messageId_ < triple.messageId_)));
379}
380
382{
383 const ScopedLock scopedLock(lock_);
384
385 receiveCallback_ = callback;
386}
387
388}
389
390}
391
392#endif // FACEBOOK_NETWORK_PACKAGED_CONNECTIONLESS_SERVER_H
This class wraps an address number with 32 bits.
Definition Address4.h:26
This class is the base class for all packaged connectionless clients.
Definition PackagedConnectionlessClient.h:40
This class implements a message.
Definition PackagedConnectionlessServer.h:54
unsigned int remainingPackages() const
Returns the number of remaining packages.
Definition PackagedConnectionlessServer.h:286
bool setPackageReceived(const unsigned int packageIndex)
Marks one package of this message as received.
Definition PackagedConnectionlessServer.h:311
const uint8_t * buffer() const
Returns the message buffer.
Definition PackagedConnectionlessServer.h:296
Buffer buffer_
The entire buffer of the message.
Definition PackagedConnectionlessServer.h:152
MessageData & operator=(const MessageData &messageData)
Assign operator.
Definition PackagedConnectionlessServer.h:327
void setRetireTimestamp(const Timestamp timestamp)
Sets or changes the retire timestamp.
Definition PackagedConnectionlessServer.h:306
Timestamp retireTimestamp() const
Returns the retire timestamp.
Definition PackagedConnectionlessServer.h:281
Timestamp retireTimestamp_
The timestamp at which this message will be retired as no further packages arrived in the meantime.
Definition PackagedConnectionlessServer.h:143
MessageData()=default
Creates an empty data object.
size_t size() const
Returns the size of the message buffer, in bytes.
Definition PackagedConnectionlessServer.h:291
std::vector< uint8_t > receivedPackages_
The received state of each package of this message.
Definition PackagedConnectionlessServer.h:149
unsigned int remainingPackages_
The number of packages which are still missing.
Definition PackagedConnectionlessServer.h:146
Definition of a triple storing an address, a port and a message id.
Definition PackagedConnectionlessServer.h:159
Triple(const Address4 &address, const Port &port, const MessageId messageId)
Creates a new triple object.
Definition PackagedConnectionlessServer.h:353
bool operator<(const Triple &triple) const
Compares two triple objects.
Definition PackagedConnectionlessServer.h:376
unsigned int messageId_
The message id of this object.
Definition PackagedConnectionlessServer.h:204
const Address4 & address() const
Returns the address of this object.
Definition PackagedConnectionlessServer.h:361
MessageId messageId() const
Returns the message id of this object.
Definition PackagedConnectionlessServer.h:371
const Port & port() const
Returns the port of this object.
Definition PackagedConnectionlessServer.h:366
Address4 address_
The address of this object.
Definition PackagedConnectionlessServer.h:198
Port port_
The port of this object.
Definition PackagedConnectionlessServer.h:201
This class is the base class for all package connectionless server.
Definition PackagedConnectionlessServer.h:35
bool onScheduler() override
The scheduler event function.
ReceiveCallback receiveCallback_
Data callback function called on new message arrivals.
Definition PackagedConnectionlessServer.h:241
std::map< Triple, MessageData > MessageMap
Definition of a map mapping message ids to massage data objects.
Definition PackagedConnectionlessServer.h:210
~PackagedConnectionlessServer() override
Destructs a connectionless server object.
void setReceiveCallback(const ReceiveCallback &callback)
Sets the receive data callback function.
Definition PackagedConnectionlessServer.h:381
MessageMap connectionlessServerMessageMap
The map holding all partially received message.
Definition PackagedConnectionlessServer.h:250
Buffer packageBuffer_
Intermediate buffer storing individual parts of a large message.
Definition PackagedConnectionlessServer.h:247
PackagedConnectionlessServer()
Creates a new connectionless server object.
uint32_t MessageId
Definition of a message id.
Definition PackagedSocket.h:215
This class wraps a port number with 16 bits.
Definition Port.h:26
This class is the base class for all server.
Definition Server.h:26
Buffer buffer_
The socket buffer of this server.
Definition Server.h:57
Address4 address() const
Returns the own address of this socket.
std::vector< uint8_t > Buffer
Definition of a vector holding 8 bit values.
Definition Socket.h:76
Port port() const
Returns the own port of this socket.
Lock lock_
Socket lock.
Definition Socket.h:187
This class implements a scoped lock object for recursive lock objects.
Definition Lock.h:147
This class implements a timestamp.
Definition Timestamp.h:64
The namespace covering the entire Ocean framework.
Definition Accessor.h:15