OpenTTD Source: src/network/core/packet.cpp Source File

OpenTTD Source 1.11.0-RC1

packet.cpp
Go to the documentation of this file.
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
12 #include "../../stdafx.h"
13 #include "../../string_func.h"
14
15 #include "packet.h"
16
17 #include "../../safeguards.h"
18
23 Packet::Packet(NetworkSocketHandler *cs)
24 {
25 assert(cs != nullptr);
26
27 this->cs = cs;
28 this->next = nullptr;
29 this->pos = 0; // We start reading from here
30 this->size = 0;
31 this->buffer = MallocT<byte>(SEND_MTU);
32 }
33
38 Packet::Packet(PacketType type)
39 {
40 this->cs = nullptr;
41 this->next = nullptr;
42
43 /* Skip the size so we can write that in before sending the packet */
44 this->pos = 0;
45 this->size = sizeof(PacketSize);
46 this->buffer = MallocT<byte>(SEND_MTU);
47 this->buffer[this->size++] = type;
48 }
49
53 Packet::~Packet()
54 {
55 free(this->buffer);
56 }
57
61 void Packet::PrepareToSend()
62 {
63 assert(this->cs == nullptr && this->next == nullptr);
64
65 this->buffer[0] = GB(this->size, 0, 8);
66 this->buffer[1] = GB(this->size, 8, 8);
67
68 this->pos = 0; // We start reading from here
69 }
70
71 /*
72 * The next couple of functions make sure we can send
73 * uint8, uint16, uint32 and uint64 endian-safe
74 * over the network. The least significant bytes are
75 * sent first.
76 *
77 * So 0x01234567 would be sent as 67 45 23 01.
78 *
79 * A bool is sent as a uint8 where zero means false
80 * and non-zero means true.
81 */
82
87 void Packet::Send_bool(bool data)
88 {
89 this->Send_uint8(data ? 1 : 0);
90 }
91
96 void Packet::Send_uint8(uint8 data)
97 {
98 assert(this->size < SEND_MTU - sizeof(data));
99 this->buffer[this->size++] = data;
100 }
101
106 void Packet::Send_uint16(uint16 data)
107 {
108 assert(this->size < SEND_MTU - sizeof(data));
109 this->buffer[this->size++] = GB(data, 0, 8);
110 this->buffer[this->size++] = GB(data, 8, 8);
111 }
112
117 void Packet::Send_uint32(uint32 data)
118 {
119 assert(this->size < SEND_MTU - sizeof(data));
120 this->buffer[this->size++] = GB(data, 0, 8);
121 this->buffer[this->size++] = GB(data, 8, 8);
122 this->buffer[this->size++] = GB(data, 16, 8);
123 this->buffer[this->size++] = GB(data, 24, 8);
124 }
125
130 void Packet::Send_uint64(uint64 data)
131 {
132 assert(this->size < SEND_MTU - sizeof(data));
133 this->buffer[this->size++] = GB(data, 0, 8);
134 this->buffer[this->size++] = GB(data, 8, 8);
135 this->buffer[this->size++] = GB(data, 16, 8);
136 this->buffer[this->size++] = GB(data, 24, 8);
137 this->buffer[this->size++] = GB(data, 32, 8);
138 this->buffer[this->size++] = GB(data, 40, 8);
139 this->buffer[this->size++] = GB(data, 48, 8);
140 this->buffer[this->size++] = GB(data, 56, 8);
141 }
142
148 void Packet::Send_string(const char *data)
149 {
150 assert(data != nullptr);
151 /* The <= *is* valid due to the fact that we are comparing sizes and not the index. */
152 assert(this->size + strlen(data) + 1 <= SEND_MTU);
153 while ((this->buffer[this->size++] = *data++) != '\0') {}
154 }
155
156
157 /*
158 * Receiving commands
159 * Again, the next couple of functions are endian-safe
160 * see the comment before Send_bool for more info.
161 */
162
163
169 bool Packet::CanReadFromPacket(uint bytes_to_read)
170 {
171 /* Don't allow reading from a quit client/client who send bad data */
172 if (this->cs->HasClientQuit()) return false;
173
174 /* Check if variable is within packet-size */
175 if (this->pos + bytes_to_read > this->size) {
176 this->cs->NetworkSocketHandler::CloseConnection();
177 return false;
178 }
179
180 return true;
181 }
182
186 void Packet::ReadRawPacketSize()
187 {
188 assert(this->cs != nullptr && this->next == nullptr);
189 this->size = (PacketSize)this->buffer[0];
190 this->size += (PacketSize)this->buffer[1] << 8;
191 }
192
196 void Packet::PrepareToRead()
197 {
198 this->ReadRawPacketSize();
199
200 /* Put the position on the right place */
201 this->pos = sizeof(PacketSize);
202 }
203
208 bool Packet::Recv_bool()
209 {
210 return this->Recv_uint8() != 0;
211 }
212
217 uint8 Packet::Recv_uint8()
218 {
219 uint8 n;
220
221 if (!this->CanReadFromPacket(sizeof(n))) return 0;
222
223 n = this->buffer[this->pos++];
224 return n;
225 }
226
231 uint16 Packet::Recv_uint16()
232 {
233 uint16 n;
234
235 if (!this->CanReadFromPacket(sizeof(n))) return 0;
236
237 n = (uint16)this->buffer[this->pos++];
238 n += (uint16)this->buffer[this->pos++] << 8;
239 return n;
240 }
241
246 uint32 Packet::Recv_uint32()
247 {
248 uint32 n;
249
250 if (!this->CanReadFromPacket(sizeof(n))) return 0;
251
252 n = (uint32)this->buffer[this->pos++];
253 n += (uint32)this->buffer[this->pos++] << 8;
254 n += (uint32)this->buffer[this->pos++] << 16;
255 n += (uint32)this->buffer[this->pos++] << 24;
256 return n;
257 }
258
263 uint64 Packet::Recv_uint64()
264 {
265 uint64 n;
266
267 if (!this->CanReadFromPacket(sizeof(n))) return 0;
268
269 n = (uint64)this->buffer[this->pos++];
270 n += (uint64)this->buffer[this->pos++] << 8;
271 n += (uint64)this->buffer[this->pos++] << 16;
272 n += (uint64)this->buffer[this->pos++] << 24;
273 n += (uint64)this->buffer[this->pos++] << 32;
274 n += (uint64)this->buffer[this->pos++] << 40;
275 n += (uint64)this->buffer[this->pos++] << 48;
276 n += (uint64)this->buffer[this->pos++] << 56;
277 return n;
278 }
279
286 void Packet::Recv_string(char *buffer, size_t size, StringValidationSettings settings)
287 {
288 PacketSize pos;
289 char *bufp = buffer;
290 const char *last = buffer + size - 1;
291
292 /* Don't allow reading from a closed socket */
293 if (cs->HasClientQuit()) return;
294
295 pos = this->pos;
296 while (--size > 0 && pos < this->size && (*buffer++ = this->buffer[pos++]) != '\0') {}
297
298 if (size == 0 || pos == this->size) {
299 *buffer = '\0';
300 /* If size was sooner to zero then the string in the stream
301 * skip till the \0, so than packet can be read out correctly for the rest */
302 while (pos < this->size && this->buffer[pos] != '\0') pos++;
303 pos++;
304 }
305 this->pos = pos;
306
307 str_validate(bufp, last, settings);
308 }
Packet::PrepareToSend
void PrepareToSend()
Writes the packet size from the raw packet from packet->size.
Definition: packet.cpp:61
Packet::Recv_string
void Recv_string(char *buffer, size_t size, StringValidationSettings settings=SVS_REPLACE_WITH_QUESTION_MARK)
Reads a string till it finds a '\0' in the stream.
Definition: packet.cpp:286
GB
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
Definition: bitmath_func.hpp:32
str_validate
void str_validate(char *str, const char *last, StringValidationSettings settings)
Scans the string for valid characters and if it finds invalid ones, replaces them with a question mar...
Definition: string.cpp:237
Packet::buffer
byte * buffer
The buffer of this packet, of basically variable length up to SEND_MTU.
Definition: packet.h:52
NetworkSocketHandler
SocketHandler for all network sockets in OpenTTD.
Definition: core.h:41
Packet::Send_uint8
void Send_uint8(uint8 data)
Package a 8 bits integer in the packet.
Definition: packet.cpp:96
PacketType
uint8 PacketType
Identifier for the packet.
Definition: packet.h:20
Packet::Send_uint32
void Send_uint32(uint32 data)
Package a 32 bits integer in the packet.
Definition: packet.cpp:117
Packet::Recv_uint32
uint32 Recv_uint32()
Read a 32 bits integer from the packet.
Definition: packet.cpp:246
Packet::Send_string
void Send_string(const char *data)
Sends a string over the network.
Definition: packet.cpp:148
Packet::PrepareToRead
void PrepareToRead()
Prepares the packet so it can be read.
Definition: packet.cpp:196
Packet::size
PacketSize size
The size of the whole packet for received packets.
Definition: packet.h:48
SEND_MTU
static const uint16 SEND_MTU
Number of bytes we can pack in a single packet.
Definition: config.h:33
Packet::Send_uint16
void Send_uint16(uint16 data)
Package a 16 bits integer in the packet.
Definition: packet.cpp:106
settings
fluid_settings_t * settings
FluidSynth settings handle.
Definition: fluidsynth.cpp:21
Packet::next
Packet * next
The next packet.
Definition: packet.h:42
Packet::CanReadFromPacket
bool CanReadFromPacket(uint bytes_to_read)
Is it safe to read from the packet, i.e.
Definition: packet.cpp:169
Packet::ReadRawPacketSize
void ReadRawPacketSize()
Reads the packet size from the raw packet and stores it in the packet->size.
Definition: packet.cpp:186
StringValidationSettings
StringValidationSettings
Settings for the string validation.
Definition: string_type.h:48
Packet::Send_bool
void Send_bool(bool data)
Package a boolean in the packet.
Definition: packet.cpp:87
NetworkSocketHandler::HasClientQuit
bool HasClientQuit() const
Whether the current client connected to the socket has quit.
Definition: core.h:67
Packet::~Packet
~Packet()
Free the buffer of this packet.
Definition: packet.cpp:53
PacketSize
uint16 PacketSize
Size of the whole packet.
Definition: packet.h:19
Packet::Recv_bool
bool Recv_bool()
Read a boolean from the packet.
Definition: packet.cpp:208
Packet::Send_uint64
void Send_uint64(uint64 data)
Package a 64 bits integer in the packet.
Definition: packet.cpp:130
packet.h
Packet::cs
NetworkSocketHandler * cs
Socket we're associated with.
Definition: packet.h:56
Packet::Recv_uint8
uint8 Recv_uint8()
Read a 8 bits integer from the packet.
Definition: packet.cpp:217
Packet::Packet
Packet(NetworkSocketHandler *cs)
Create a packet that is used to read from a network socket.
Definition: packet.cpp:23
Packet::Recv_uint64
uint64 Recv_uint64()
Read a 64 bits integer from the packet.
Definition: packet.cpp:263
free
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: stdafx.h:454
Packet::Recv_uint16
uint16 Recv_uint16()
Read a 16 bits integer from the packet.
Definition: packet.cpp:231
Packet::pos
PacketSize pos
The current read/write position in the packet.
Definition: packet.h:50