summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2010-11-30 13:22:29 +0000
committerrubidium <rubidium@openttd.org>2010-11-30 13:22:29 +0000
commit9c83a8975fe93568d4a3c44bd273e846b18d8e3f (patch)
treef673aa11b963cb6dce5c08220619b7be3d81b439
parent44937dfa5e9b7942ba46c7b2a0f4414b3dc9f0a9 (diff)
downloadopenttd-9c83a8975fe93568d4a3c44bd273e846b18d8e3f.tar.xz
(svn r21357) -Codechange: make it possible to resize the packet's buffer
-rw-r--r--src/network/core/packet.cpp28
-rw-r--r--src/network/core/packet.h7
-rw-r--r--src/network/core/tcp.cpp5
-rw-r--r--src/network/core/udp.cpp3
4 files changed, 30 insertions, 13 deletions
diff --git a/src/network/core/packet.cpp b/src/network/core/packet.cpp
index 5f48ed055..cc098793b 100644
--- a/src/network/core/packet.cpp
+++ b/src/network/core/packet.cpp
@@ -26,10 +26,11 @@ Packet::Packet(NetworkSocketHandler *cs)
{
assert(cs != NULL);
- this->cs = cs;
- this->next = NULL;
- this->pos = 0; // We start reading from here
- this->size = 0;
+ this->cs = cs;
+ this->next = NULL;
+ this->pos = 0; // We start reading from here
+ this->size = 0;
+ this->buffer = MallocT<byte>(SEND_MTU);
}
/**
@@ -44,10 +45,19 @@ Packet::Packet(PacketType type)
/* Skip the size so we can write that in before sending the packet */
this->pos = 0;
this->size = sizeof(PacketSize);
+ this->buffer = MallocT<byte>(SEND_MTU);
this->buffer[this->size++] = type;
}
/**
+ * Free the buffer of this packet.
+ */
+Packet::~Packet()
+{
+ free(this->buffer);
+}
+
+/**
* Writes the packet size from the raw packet from packet->size
*/
void Packet::PrepareToSend()
@@ -79,20 +89,20 @@ void Packet::Send_bool(bool data)
void Packet::Send_uint8(uint8 data)
{
- assert(this->size < sizeof(this->buffer) - sizeof(data));
+ assert(this->size < SEND_MTU - sizeof(data));
this->buffer[this->size++] = data;
}
void Packet::Send_uint16(uint16 data)
{
- assert(this->size < sizeof(this->buffer) - sizeof(data));
+ assert(this->size < SEND_MTU - sizeof(data));
this->buffer[this->size++] = GB(data, 0, 8);
this->buffer[this->size++] = GB(data, 8, 8);
}
void Packet::Send_uint32(uint32 data)
{
- assert(this->size < sizeof(this->buffer) - sizeof(data));
+ assert(this->size < SEND_MTU - sizeof(data));
this->buffer[this->size++] = GB(data, 0, 8);
this->buffer[this->size++] = GB(data, 8, 8);
this->buffer[this->size++] = GB(data, 16, 8);
@@ -101,7 +111,7 @@ void Packet::Send_uint32(uint32 data)
void Packet::Send_uint64(uint64 data)
{
- assert(this->size < sizeof(this->buffer) - sizeof(data));
+ assert(this->size < SEND_MTU - sizeof(data));
this->buffer[this->size++] = GB(data, 0, 8);
this->buffer[this->size++] = GB(data, 8, 8);
this->buffer[this->size++] = GB(data, 16, 8);
@@ -121,7 +131,7 @@ void Packet::Send_string(const char *data)
{
assert(data != NULL);
/* The <= *is* valid due to the fact that we are comparing sizes and not the index. */
- assert(this->size + strlen(data) + 1 <= sizeof(this->buffer));
+ assert(this->size + strlen(data) + 1 <= SEND_MTU);
while ((this->buffer[this->size++] = *data++) != '\0') {}
}
diff --git a/src/network/core/packet.h b/src/network/core/packet.h
index 38cd528ef..50a3f5cde 100644
--- a/src/network/core/packet.h
+++ b/src/network/core/packet.h
@@ -42,14 +42,17 @@ struct Packet {
PacketSize size;
/** The current read/write position in the packet */
PacketSize pos;
- /** The buffer of this packet */
- byte buffer[SEND_MTU];
+ /** The buffer of this packet, of basically variable length up to SEND_MTU. */
+ byte *buffer;
+
private:
+ /** Socket we're associated with. */
NetworkSocketHandler *cs;
public:
Packet(NetworkSocketHandler *cs);
Packet(PacketType type);
+ ~Packet();
/* Sending/writing of packets */
void PrepareToSend();
diff --git a/src/network/core/tcp.cpp b/src/network/core/tcp.cpp
index 3f59efba9..c35b029a2 100644
--- a/src/network/core/tcp.cpp
+++ b/src/network/core/tcp.cpp
@@ -63,6 +63,11 @@ void NetworkTCPSocketHandler::Send_Packet(Packet *packet)
packet->PrepareToSend();
+ /* Reallocate the packet as in 99+% of the times we send at most 25 bytes and
+ * keeping the other 1400+ bytes wastes memory, especially when someone tries
+ * to do a denial of service attack! */
+ packet->buffer = ReallocT(packet->buffer, packet->size);
+
/* Locate last packet buffered for the client */
p = this->packet_queue;
if (p == NULL) {
diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp
index 1163ee3bb..b153cdf88 100644
--- a/src/network/core/udp.cpp
+++ b/src/network/core/udp.cpp
@@ -121,12 +121,11 @@ void NetworkUDPSocketHandler::ReceivePackets()
memset(&client_addr, 0, sizeof(client_addr));
Packet p(this);
- int packet_len = sizeof(p.buffer);
socklen_t client_len = sizeof(client_addr);
/* Try to receive anything */
SetNonBlocking(s->second); // Some OSes seem to lose the non-blocking status of the socket
- int nbytes = recvfrom(s->second, (char*)p.buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len);
+ int nbytes = recvfrom(s->second, (char*)p.buffer, SEND_MTU, 0, (struct sockaddr *)&client_addr, &client_len);
/* We got some bytes for the base header of the packet. */
if (nbytes > 2) {