1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
8 /**
9  * @file packet.cpp Basic functions to create, fill and read packets.
10  */
11 
12 #include "../../stdafx.h"
13 #include "../../string_func.h"
14 
15 #include "packet.h"
16 
17 #include "../../safeguards.h"
18 
19 /**
20  * Create a packet that is used to read from a network socket.
21  * @param cs                The socket handler associated with the socket we are reading from.
22  * @param limit             The maximum size of packets to accept.
23  * @param initial_read_size The initial amount of data to transfer from the socket into the
24  *                          packet. This defaults to just the required bytes to determine the
25  *                          packet's size. That default is the wanted for streams such as TCP
26  *                          as you do not want to read data of the next packet yet. For UDP
27  *                          you need to read the whole packet at once otherwise you might
28  *                          loose some the data of the packet, so there you pass the maximum
29  *                          size for the packet you expect from the network.
30  */
Packet(NetworkSocketHandler * cs,size_t limit,size_t initial_read_size)31 Packet::Packet(NetworkSocketHandler *cs, size_t limit, size_t initial_read_size) : next(nullptr), pos(0), limit(limit)
32 {
33 	assert(cs != nullptr);
34 
35 	this->cs = cs;
36 	this->buffer.resize(initial_read_size);
37 }
38 
39 /**
40  * Creates a packet to send
41  * @param type  The type of the packet to send
42  * @param limit The maximum number of bytes the packet may have. Default is COMPAT_MTU.
43  *              Be careful of compatibility with older clients/servers when changing
44  *              the limit as it might break things if the other side is not expecting
45  *              much larger packets than what they support.
46  */
Packet(PacketType type,size_t limit)47 Packet::Packet(PacketType type, size_t limit) : next(nullptr), pos(0), limit(limit), cs(nullptr)
48 {
49 	/* Allocate space for the the size so we can write that in just before sending the packet. */
50 	this->Send_uint16(0);
51 	this->Send_uint8(type);
52 }
53 
54 /**
55  * Add the given Packet to the end of the queue of packets.
56  * @param queue  The pointer to the begin of the queue.
57  * @param packet The packet to append to the queue.
58  */
AddToQueue(Packet ** queue,Packet * packet)59 /* static */ void Packet::AddToQueue(Packet **queue, Packet *packet)
60 {
61 	while (*queue != nullptr) queue = &(*queue)->next;
62 	*queue = packet;
63 }
64 
65 /**
66  * Pop the packet from the begin of the queue and set the
67  * begin of the queue to the second element in the queue.
68  * @param queue  The pointer to the begin of the queue.
69  * @return The Packet that used to be a the begin of the queue.
70  */
PopFromQueue(Packet ** queue)71 /* static */ Packet *Packet::PopFromQueue(Packet **queue)
72 {
73 	Packet *p = *queue;
74 	*queue = p->next;
75 	p->next = nullptr;
76 	return p;
77 }
78 
79 
80 /**
81  * Writes the packet size from the raw packet from packet->size
82  */
PrepareToSend()83 void Packet::PrepareToSend()
84 {
85 	assert(this->cs == nullptr && this->next == nullptr);
86 
87 	this->buffer[0] = GB(this->Size(), 0, 8);
88 	this->buffer[1] = GB(this->Size(), 8, 8);
89 
90 	this->pos  = 0; // We start reading from here
91 	this->buffer.shrink_to_fit();
92 }
93 
94 /**
95  * Is it safe to write to the packet, i.e. didn't we run over the buffer?
96  * @param bytes_to_write The amount of bytes we want to try to write.
97  * @return True iff the given amount of bytes can be written to the packet.
98  */
CanWriteToPacket(size_t bytes_to_write)99 bool Packet::CanWriteToPacket(size_t bytes_to_write)
100 {
101 	return this->Size() + bytes_to_write <= this->limit;
102 }
103 
104 /*
105  * The next couple of functions make sure we can send
106  *  uint8, uint16, uint32 and uint64 endian-safe
107  *  over the network. The least significant bytes are
108  *  sent first.
109  *
110  *  So 0x01234567 would be sent as 67 45 23 01.
111  *
112  * A bool is sent as a uint8 where zero means false
113  *  and non-zero means true.
114  */
115 
116 /**
117  * Package a boolean in the packet.
118  * @param data The data to send.
119  */
Send_bool(bool data)120 void Packet::Send_bool(bool data)
121 {
122 	this->Send_uint8(data ? 1 : 0);
123 }
124 
125 /**
126  * Package a 8 bits integer in the packet.
127  * @param data The data to send.
128  */
Send_uint8(uint8 data)129 void Packet::Send_uint8(uint8 data)
130 {
131 	assert(this->CanWriteToPacket(sizeof(data)));
132 	this->buffer.emplace_back(data);
133 }
134 
135 /**
136  * Package a 16 bits integer in the packet.
137  * @param data The data to send.
138  */
Send_uint16(uint16 data)139 void Packet::Send_uint16(uint16 data)
140 {
141 	assert(this->CanWriteToPacket(sizeof(data)));
142 	this->buffer.emplace_back(GB(data, 0, 8));
143 	this->buffer.emplace_back(GB(data, 8, 8));
144 }
145 
146 /**
147  * Package a 32 bits integer in the packet.
148  * @param data The data to send.
149  */
Send_uint32(uint32 data)150 void Packet::Send_uint32(uint32 data)
151 {
152 	assert(this->CanWriteToPacket(sizeof(data)));
153 	this->buffer.emplace_back(GB(data,  0, 8));
154 	this->buffer.emplace_back(GB(data,  8, 8));
155 	this->buffer.emplace_back(GB(data, 16, 8));
156 	this->buffer.emplace_back(GB(data, 24, 8));
157 }
158 
159 /**
160  * Package a 64 bits integer in the packet.
161  * @param data The data to send.
162  */
Send_uint64(uint64 data)163 void Packet::Send_uint64(uint64 data)
164 {
165 	assert(this->CanWriteToPacket(sizeof(data)));
166 	this->buffer.emplace_back(GB(data,  0, 8));
167 	this->buffer.emplace_back(GB(data,  8, 8));
168 	this->buffer.emplace_back(GB(data, 16, 8));
169 	this->buffer.emplace_back(GB(data, 24, 8));
170 	this->buffer.emplace_back(GB(data, 32, 8));
171 	this->buffer.emplace_back(GB(data, 40, 8));
172 	this->buffer.emplace_back(GB(data, 48, 8));
173 	this->buffer.emplace_back(GB(data, 56, 8));
174 }
175 
176 /**
177  * Sends a string over the network. It sends out
178  * the string + '\0'. No size-byte or something.
179  * @param data The string to send
180  */
Send_string(const std::string_view data)181 void Packet::Send_string(const std::string_view data)
182 {
183 	assert(this->CanWriteToPacket(data.size() + 1));
184 	this->buffer.insert(this->buffer.end(), data.begin(), data.end());
185 	this->buffer.emplace_back('\0');
186 }
187 
188 /**
189  * Send as many of the bytes as possible in the packet. This can mean
190  * that it is possible that not all bytes are sent. To cope with this
191  * the function returns the amount of bytes that were actually sent.
192  * @param begin The begin of the buffer to send.
193  * @param end   The end of the buffer to send.
194  * @return The number of bytes that were added to this packet.
195  */
Send_bytes(const byte * begin,const byte * end)196 size_t Packet::Send_bytes(const byte *begin, const byte *end)
197 {
198 	size_t amount = std::min<size_t>(end - begin, this->limit - this->Size());
199 	this->buffer.insert(this->buffer.end(), begin, begin + amount);
200 	return amount;
201 }
202 
203 /*
204  * Receiving commands
205  * Again, the next couple of functions are endian-safe
206  *  see the comment before Send_bool for more info.
207  */
208 
209 
210 /**
211  * Is it safe to read from the packet, i.e. didn't we run over the buffer?
212  * In case \c close_connection is true, the connection will be closed when one would
213  * overrun the buffer. When it is false, the connection remains untouched.
214  * @param bytes_to_read    The amount of bytes we want to try to read.
215  * @param close_connection Whether to close the connection if one cannot read that amount.
216  * @return True if that is safe, otherwise false.
217  */
CanReadFromPacket(size_t bytes_to_read,bool close_connection)218 bool Packet::CanReadFromPacket(size_t bytes_to_read, bool close_connection)
219 {
220 	/* Don't allow reading from a quit client/client who send bad data */
221 	if (this->cs->HasClientQuit()) return false;
222 
223 	/* Check if variable is within packet-size */
224 	if (this->pos + bytes_to_read > this->Size()) {
225 		if (close_connection) this->cs->NetworkSocketHandler::MarkClosed();
226 		return false;
227 	}
228 
229 	return true;
230 }
231 
232 /**
233  * Check whether the packet, given the position of the "write" pointer, has read
234  * enough of the packet to contain its size.
235  * @return True iff there is enough data in the packet to contain the packet's size.
236  */
HasPacketSizeData() const237 bool Packet::HasPacketSizeData() const
238 {
239 	return this->pos >= sizeof(PacketSize);
240 }
241 
242 /**
243  * Get the number of bytes in the packet.
244  * When sending a packet this is the size of the data up to that moment.
245  * When receiving a packet (before PrepareToRead) this is the allocated size for the data to be read.
246  * When reading a packet (after PrepareToRead) this is the full size of the packet.
247  * @return The packet's size.
248  */
Size() const249 size_t Packet::Size() const
250 {
251 	return this->buffer.size();
252 }
253 
254 /**
255  * Reads the packet size from the raw packet and stores it in the packet->size
256  * @return True iff the packet size seems plausible.
257  */
ParsePacketSize()258 bool Packet::ParsePacketSize()
259 {
260 	assert(this->cs != nullptr && this->next == nullptr);
261 	size_t size = (size_t)this->buffer[0];
262 	size       += (size_t)this->buffer[1] << 8;
263 
264 	/* If the size of the packet is less than the bytes required for the size and type of
265 	 * the packet, or more than the allowed limit, then something is wrong with the packet.
266 	 * In those cases the packet can generally be regarded as containing garbage data. */
267 	if (size < sizeof(PacketSize) + sizeof(PacketType) || size > this->limit) return false;
268 
269 	this->buffer.resize(size);
270 	this->pos = sizeof(PacketSize);
271 	return true;
272 }
273 
274 /**
275  * Prepares the packet so it can be read
276  */
PrepareToRead()277 void Packet::PrepareToRead()
278 {
279 	/* Put the position on the right place */
280 	this->pos = sizeof(PacketSize);
281 }
282 
283 /**
284  * Get the \c PacketType from this packet.
285  * @return The packet type.
286  */
GetPacketType() const287 PacketType Packet::GetPacketType() const
288 {
289 	assert(this->Size() >= sizeof(PacketSize) + sizeof(PacketType));
290 	return static_cast<PacketType>(buffer[sizeof(PacketSize)]);
291 }
292 
293 /**
294  * Read a boolean from the packet.
295  * @return The read data.
296  */
Recv_bool()297 bool Packet::Recv_bool()
298 {
299 	return this->Recv_uint8() != 0;
300 }
301 
302 /**
303  * Read a 8 bits integer from the packet.
304  * @return The read data.
305  */
Recv_uint8()306 uint8 Packet::Recv_uint8()
307 {
308 	uint8 n;
309 
310 	if (!this->CanReadFromPacket(sizeof(n), true)) return 0;
311 
312 	n = this->buffer[this->pos++];
313 	return n;
314 }
315 
316 /**
317  * Read a 16 bits integer from the packet.
318  * @return The read data.
319  */
Recv_uint16()320 uint16 Packet::Recv_uint16()
321 {
322 	uint16 n;
323 
324 	if (!this->CanReadFromPacket(sizeof(n), true)) return 0;
325 
326 	n  = (uint16)this->buffer[this->pos++];
327 	n += (uint16)this->buffer[this->pos++] << 8;
328 	return n;
329 }
330 
331 /**
332  * Read a 32 bits integer from the packet.
333  * @return The read data.
334  */
Recv_uint32()335 uint32 Packet::Recv_uint32()
336 {
337 	uint32 n;
338 
339 	if (!this->CanReadFromPacket(sizeof(n), true)) return 0;
340 
341 	n  = (uint32)this->buffer[this->pos++];
342 	n += (uint32)this->buffer[this->pos++] << 8;
343 	n += (uint32)this->buffer[this->pos++] << 16;
344 	n += (uint32)this->buffer[this->pos++] << 24;
345 	return n;
346 }
347 
348 /**
349  * Read a 64 bits integer from the packet.
350  * @return The read data.
351  */
Recv_uint64()352 uint64 Packet::Recv_uint64()
353 {
354 	uint64 n;
355 
356 	if (!this->CanReadFromPacket(sizeof(n), true)) return 0;
357 
358 	n  = (uint64)this->buffer[this->pos++];
359 	n += (uint64)this->buffer[this->pos++] << 8;
360 	n += (uint64)this->buffer[this->pos++] << 16;
361 	n += (uint64)this->buffer[this->pos++] << 24;
362 	n += (uint64)this->buffer[this->pos++] << 32;
363 	n += (uint64)this->buffer[this->pos++] << 40;
364 	n += (uint64)this->buffer[this->pos++] << 48;
365 	n += (uint64)this->buffer[this->pos++] << 56;
366 	return n;
367 }
368 
369 /**
370  * Reads characters (bytes) from the packet until it finds a '\0', or reaches a
371  * maximum of \c length characters.
372  * When the '\0' has not been reached in the first \c length read characters,
373  * more characters are read from the packet until '\0' has been reached. However,
374  * these characters will not end up in the returned string.
375  * The length of the returned string will be at most \c length - 1 characters.
376  * @param length   The maximum length of the string including '\0'.
377  * @param settings The string validation settings.
378  * @return The validated string.
379  */
Recv_string(size_t length,StringValidationSettings settings)380 std::string Packet::Recv_string(size_t length, StringValidationSettings settings)
381 {
382 	assert(length > 1);
383 
384 	/* Both loops with Recv_uint8 terminate when reading past the end of the
385 	 * packet as Recv_uint8 then closes the connection and returns 0. */
386 	std::string str;
387 	char character;
388 	while (--length > 0 && (character = this->Recv_uint8()) != '\0') str.push_back(character);
389 
390 	if (length == 0) {
391 		/* The string in the packet was longer. Read until the termination. */
392 		while (this->Recv_uint8() != '\0') {}
393 	}
394 
395 	return StrMakeValid(str, settings);
396 }
397 
398 /**
399  * Get the amount of bytes that are still available for the Transfer functions.
400  * @return The number of bytes that still have to be transfered.
401  */
RemainingBytesToTransfer() const402 size_t Packet::RemainingBytesToTransfer() const
403 {
404 	return this->Size() - this->pos;
405 }
406