(svn r8521) -Codechange: initial step in converting Packet to a class; make and use constructors and functions related to the reading/saving the packet size.

This commit is contained in:
rubidium 2007-02-01 22:30:35 +00:00
parent 15980fc023
commit 99f860e686
8 changed files with 143 additions and 140 deletions

View File

@ -17,34 +17,60 @@
/* Do not want to include functions.h and all required headers */
extern void NORETURN CDECL error(const char *str, ...);
/**
* Create a packet that is used to read from a network socket
* @param cs the socket handler associated with the socket we are reading from
*/
Packet::Packet(NetworkSocketHandler *cs)
{
assert(cs != NULL);
this->cs = cs;
this->next = NULL;
this->pos = 0; // We start reading from here
this->size = 0;
}
/**
* Creates a packet to send
* @param type of the packet to send
*/
Packet::Packet(PacketType type)
{
this->cs = NULL;
this->next = NULL;
/* Skip the size so we can write that in before sending the packet */
this->pos = 0;
this->size = sizeof(PacketSize);
this->buffer[this->size++] = type;
}
/**
* Create a packet for sending
* @param type the of packet
* @return the newly created packet
*/
Packet *NetworkSend_Init(const PacketType type)
Packet *NetworkSend_Init(PacketType type)
{
Packet *packet = MallocT<Packet>(1);
Packet *packet = new Packet(type);
/* An error is inplace here, because it simply means we ran out of memory. */
if (packet == NULL) error("Failed to allocate Packet");
/* Skip the size so we can write that in before sending the packet */
packet->size = sizeof(packet->size);
packet->buffer[packet->size++] = type;
packet->pos = 0;
return packet;
}
/**
* Writes the packet size from the raw packet from packet->size
* @param packet the packet to write the size of
*/
void NetworkSend_FillPacketSize(Packet *packet)
void Packet::PrepareToSend()
{
packet->buffer[0] = GB(packet->size, 0, 8);
packet->buffer[1] = GB(packet->size, 8, 8);
assert(this->cs == NULL && this->next == NULL);
this->buffer[0] = GB(this->size, 0, 8);
this->buffer[1] = GB(this->size, 8, 8);
this->pos = 0; // We start reading from here
}
/**
@ -129,12 +155,23 @@ static inline bool CanReadFromPacket(NetworkSocketHandler *cs, const Packet *pac
/**
* Reads the packet size from the raw packet and stores it in the packet->size
* @param packet the packet to read the size of
*/
void NetworkRecv_ReadPacketSize(Packet *packet)
void Packet::ReadRawPacketSize()
{
packet->size = (uint16)packet->buffer[0];
packet->size += (uint16)packet->buffer[1] << 8;
assert(this->cs != NULL && this->next == NULL);
this->size = (PacketSize)this->buffer[0];
this->size += (PacketSize)this->buffer[1] << 8;
}
/**
* Prepares the packet so it can be read
*/
void Packet::PrepareToRead()
{
this->ReadRawPacketSize();
/* Put the position on the right place */
this->pos = sizeof(PacketSize);
}
uint8 NetworkRecv_uint8(NetworkSocketHandler *cs, Packet *packet)

View File

@ -35,18 +35,27 @@ struct Packet {
PacketSize pos;
/** The buffer of this packet */
byte buffer[SEND_MTU];
private:
NetworkSocketHandler *cs;
public:
Packet(NetworkSocketHandler *cs);
Packet(PacketType type);
void PrepareToSend();
void ReadRawPacketSize();
void PrepareToRead();
};
Packet *NetworkSend_Init(const PacketType type);
void NetworkSend_FillPacketSize(Packet *packet);
Packet *NetworkSend_Init(PacketType type);
void NetworkSend_uint8 (Packet *packet, uint8 data);
void NetworkSend_uint16(Packet *packet, uint16 data);
void NetworkSend_uint32(Packet *packet, uint32 data);
void NetworkSend_uint64(Packet *packet, uint64 data);
void NetworkSend_string(Packet *packet, const char* data);
void NetworkRecv_ReadPacketSize(Packet *packet);
uint8 NetworkRecv_uint8 (NetworkSocketHandler *cs, Packet *packet);
uint16 NetworkRecv_uint16(NetworkSocketHandler *cs, Packet *packet);
uint32 NetworkRecv_uint32(NetworkSocketHandler *cs, Packet *packet);

View File

@ -74,10 +74,7 @@ void NetworkSend_Packet(Packet *packet, NetworkTCPSocketHandler *cs)
Packet *p;
assert(packet != NULL);
packet->pos = 0;
packet->next = NULL;
NetworkSend_FillPacketSize(packet);
packet->PrepareToSend();
/* Locate last packet buffered for the client */
p = cs->packet_queue;
@ -133,7 +130,7 @@ bool NetworkSend_Packets(NetworkTCPSocketHandler *cs)
if (p->pos == p->size) {
/* Go to the next packet */
cs->packet_queue = p->next;
free(p);
delete p;
p = cs->packet_queue;
} else {
return true;
@ -159,11 +156,8 @@ Packet *NetworkRecv_Packet(NetworkTCPSocketHandler *cs, NetworkRecvStatus *statu
if (!cs->IsConnected()) return NULL;
if (cs->packet_recv == NULL) {
cs->packet_recv = MallocT<Packet>(1);
cs->packet_recv = new Packet(cs);
if (cs->packet_recv == NULL) error("Failed to allocate packet");
/* Set pos to zero! */
cs->packet_recv->pos = 0;
cs->packet_recv->size = 0; // Can be ommited, just for safety reasons
}
p = cs->packet_recv;
@ -192,7 +186,8 @@ Packet *NetworkRecv_Packet(NetworkTCPSocketHandler *cs, NetworkRecvStatus *statu
p->pos += res;
}
NetworkRecv_ReadPacketSize(p);
/* Read the packet size from the received packet */
p->ReadRawPacketSize();
if (p->size > SEND_MTU) {
*status = cs->CloseConnection();
@ -223,13 +218,10 @@ Packet *NetworkRecv_Packet(NetworkTCPSocketHandler *cs, NetworkRecvStatus *statu
p->pos += res;
}
/* We have a complete packet, return it! */
p->pos = 2;
p->next = NULL; // Should not be needed, but who knows...
/* Prepare for receiving a new packet */
cs->packet_recv = NULL;
p->PrepareToRead();
return p;
}

View File

@ -92,7 +92,7 @@ void NetworkUDPSocketHandler::SendPacket(Packet *p, const struct sockaddr_in *re
{
int res;
NetworkSend_FillPacketSize(p);
p->PrepareToSend();
/* Send the buffer */
res = sendto(this->sock, (const char*)p->buffer, p->size, 0, (struct sockaddr *)recv, sizeof(*recv));
@ -109,7 +109,7 @@ void NetworkUDPSocketHandler::ReceivePackets()
struct sockaddr_in client_addr;
socklen_t client_len;
int nbytes;
Packet p;
Packet p(this);
int packet_len;
if (!this->IsConnected()) return;
@ -122,7 +122,7 @@ void NetworkUDPSocketHandler::ReceivePackets()
/* We got some bytes for the base header of the packet. */
if (nbytes > 2) {
NetworkRecv_ReadPacketSize(&p);
p.PrepareToRead();
/* If the size does not match the packet must be corrupted.
* Otherwise it will be marked as corrupted later on. */
@ -133,10 +133,6 @@ void NetworkUDPSocketHandler::ReceivePackets()
return;
}
/* Put the position on the right place */
p.pos = 2;
p.next = NULL;
/* Handle the packet */
this->HandleUDPPacket(&p, &client_addr);
}

View File

@ -738,18 +738,14 @@ static void NetworkAcceptClients(void)
if (_network_ban_list[i] == NULL) continue;
if (sin.sin_addr.s_addr == inet_addr(_network_ban_list[i])) {
Packet *p = NetworkSend_Init(PACKET_SERVER_BANNED);
Packet p(PACKET_SERVER_BANNED);
p.PrepareToSend();
DEBUG(net, 1, "Banned ip tried to join (%s), refused", _network_ban_list[i]);
p->buffer[0] = p->size & 0xFF;
p->buffer[1] = p->size >> 8;
send(s, (const char*)p->buffer, p->size, 0);
send(s, (const char*)p.buffer, p.size, 0);
closesocket(s);
free(p);
banned = true;
break;
}
@ -761,16 +757,12 @@ static void NetworkAcceptClients(void)
if (cs == NULL) {
// no more clients allowed?
// Send to the client that we are full!
Packet *p = NetworkSend_Init(PACKET_SERVER_FULL);
Packet p(PACKET_SERVER_FULL);
p.PrepareToSend();
p->buffer[0] = p->size & 0xFF;
p->buffer[1] = p->size >> 8;
send(s, (const char*)p->buffer, p->size, 0);
send(s, (const char*)p.buffer, p.size, 0);
closesocket(s);
free(p);
continue;
}

View File

@ -864,7 +864,7 @@ NetworkRecvStatus NetworkClient_ReadPackets(NetworkTCPSocketHandler *cs)
DEBUG(net, 0, "[client] received invalid packet type %d", type);
}
free(p);
delete p;
}
return res;

View File

@ -1474,7 +1474,7 @@ bool NetworkServer_ReadPackets(NetworkTCPSocketHandler *cs)
} else {
DEBUG(net, 0, "[server] received invalid packet type %d", type);
}
free(p);
delete p;
}
return true;

View File

@ -63,12 +63,11 @@ public:
DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_FIND_SERVER)
{
Packet *packet;
// Just a fail-safe.. should never happen
if (!_network_udp_server)
return;
packet = NetworkSend_Init(PACKET_UDP_SERVER_RESPONSE);
Packet packet(PACKET_UDP_SERVER_RESPONSE);
// Update some game_info
_network_game_info.game_date = _date;
@ -79,12 +78,10 @@ DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_FIND_SERVER)
_network_game_info.spectators_on = NetworkSpectatorCount();
_network_game_info.grfconfig = _grfconfig;
this->Send_NetworkGameInfo(packet, &_network_game_info);
this->Send_NetworkGameInfo(&packet, &_network_game_info);
// Let the client know that we are here
this->SendPacket(packet, client_addr);
free(packet);
this->SendPacket(&packet, client_addr);
DEBUG(net, 2, "[udp] queried from '%s'", inet_ntoa(client_addr->sin_addr));
}
@ -93,7 +90,6 @@ DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_DETAIL_INFO)
{
NetworkTCPSocketHandler *cs;
NetworkClientInfo *ci;
Packet *packet;
Player *player;
byte current = 0;
int i;
@ -101,11 +97,11 @@ DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_DETAIL_INFO)
// Just a fail-safe.. should never happen
if (!_network_udp_server) return;
packet = NetworkSend_Init(PACKET_UDP_SERVER_DETAIL_INFO);
Packet packet(PACKET_UDP_SERVER_DETAIL_INFO);
/* Send the amount of active companies */
NetworkSend_uint8 (packet, NETWORK_COMPANY_INFO_VERSION);
NetworkSend_uint8 (packet, ActivePlayerCount());
NetworkSend_uint8 (&packet, NETWORK_COMPANY_INFO_VERSION);
NetworkSend_uint8 (&packet, ActivePlayerCount());
/* Fetch the latest version of everything */
NetworkPopulateCompanyInfo();
@ -118,51 +114,51 @@ DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_DETAIL_INFO)
current++;
/* Send the information */
NetworkSend_uint8(packet, current);
NetworkSend_uint8 (&packet, current);
NetworkSend_string(packet, _network_player_info[player->index].company_name);
NetworkSend_uint32(packet, _network_player_info[player->index].inaugurated_year);
NetworkSend_uint64(packet, _network_player_info[player->index].company_value);
NetworkSend_uint64(packet, _network_player_info[player->index].money);
NetworkSend_uint64(packet, _network_player_info[player->index].income);
NetworkSend_uint16(packet, _network_player_info[player->index].performance);
NetworkSend_string(&packet, _network_player_info[player->index].company_name);
NetworkSend_uint32(&packet, _network_player_info[player->index].inaugurated_year);
NetworkSend_uint64(&packet, _network_player_info[player->index].company_value);
NetworkSend_uint64(&packet, _network_player_info[player->index].money);
NetworkSend_uint64(&packet, _network_player_info[player->index].income);
NetworkSend_uint16(&packet, _network_player_info[player->index].performance);
/* Send 1 if there is a passord for the company else send 0 */
if (_network_player_info[player->index].password[0] != '\0') {
NetworkSend_uint8(packet, 1);
NetworkSend_uint8(&packet, 1);
} else {
NetworkSend_uint8(packet, 0);
NetworkSend_uint8(&packet, 0);
}
for (i = 0; i < NETWORK_VEHICLE_TYPES; i++)
NetworkSend_uint16(packet, _network_player_info[player->index].num_vehicle[i]);
NetworkSend_uint16(&packet, _network_player_info[player->index].num_vehicle[i]);
for (i = 0; i < NETWORK_STATION_TYPES; i++)
NetworkSend_uint16(packet, _network_player_info[player->index].num_station[i]);
NetworkSend_uint16(&packet, _network_player_info[player->index].num_station[i]);
/* Find the clients that are connected to this player */
FOR_ALL_CLIENTS(cs) {
ci = DEREF_CLIENT_INFO(cs);
if (ci->client_playas == player->index) {
/* The uint8 == 1 indicates that a client is following */
NetworkSend_uint8(packet, 1);
NetworkSend_string(packet, ci->client_name);
NetworkSend_string(packet, ci->unique_id);
NetworkSend_uint32(packet, ci->join_date);
NetworkSend_uint8 (&packet, 1);
NetworkSend_string(&packet, ci->client_name);
NetworkSend_string(&packet, ci->unique_id);
NetworkSend_uint32(&packet, ci->join_date);
}
}
/* Also check for the server itself */
ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
if (ci->client_playas == player->index) {
/* The uint8 == 1 indicates that a client is following */
NetworkSend_uint8(packet, 1);
NetworkSend_string(packet, ci->client_name);
NetworkSend_string(packet, ci->unique_id);
NetworkSend_uint32(packet, ci->join_date);
NetworkSend_uint8 (&packet, 1);
NetworkSend_string(&packet, ci->client_name);
NetworkSend_string(&packet, ci->unique_id);
NetworkSend_uint32(&packet, ci->join_date);
}
/* Indicates end of client list */
NetworkSend_uint8(packet, 0);
NetworkSend_uint8(&packet, 0);
}
/* And check if we have any spectators */
@ -170,10 +166,10 @@ DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_DETAIL_INFO)
ci = DEREF_CLIENT_INFO(cs);
if (!IsValidPlayer(ci->client_playas)) {
/* The uint8 == 1 indicates that a client is following */
NetworkSend_uint8(packet, 1);
NetworkSend_string(packet, ci->client_name);
NetworkSend_string(packet, ci->unique_id);
NetworkSend_uint32(packet, ci->join_date);
NetworkSend_uint8 (&packet, 1);
NetworkSend_string(&packet, ci->client_name);
NetworkSend_string(&packet, ci->unique_id);
NetworkSend_uint32(&packet, ci->join_date);
}
}
@ -181,17 +177,16 @@ DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_DETAIL_INFO)
ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
if (!IsValidPlayer(ci->client_playas)) {
/* The uint8 == 1 indicates that a client is following */
NetworkSend_uint8(packet, 1);
NetworkSend_string(packet, ci->client_name);
NetworkSend_string(packet, ci->unique_id);
NetworkSend_uint32(packet, ci->join_date);
NetworkSend_uint8 (&packet, 1);
NetworkSend_string(&packet, ci->client_name);
NetworkSend_string(&packet, ci->unique_id);
NetworkSend_uint32(&packet, ci->join_date);
}
/* Indicates end of client list */
NetworkSend_uint8(packet, 0);
NetworkSend_uint8(&packet, 0);
this->SendPacket(packet, client_addr);
free(packet);
this->SendPacket(&packet, client_addr);
}
/**
@ -213,7 +208,6 @@ DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_GET_NEWGRFS)
uint i;
const GRFConfig *in_reply[NETWORK_MAX_GRF_COUNT];
Packet *packet;
uint8 in_reply_count = 0;
uint packet_len = 0;
@ -246,20 +240,19 @@ DEF_UDP_RECEIVE_COMMAND(Server, PACKET_UDP_CLIENT_GET_NEWGRFS)
if (in_reply_count == 0) return;
packet = NetworkSend_Init(PACKET_UDP_SERVER_NEWGRFS);
NetworkSend_uint8 (packet, in_reply_count);
Packet packet(PACKET_UDP_SERVER_NEWGRFS);
NetworkSend_uint8 (&packet, in_reply_count);
for (i = 0; i < in_reply_count; i++) {
char name[NETWORK_GRF_NAME_LENGTH];
/* The name could be an empty string, if so take the filename */
ttd_strlcpy(name, (in_reply[i]->name != NULL && !StrEmpty(in_reply[i]->name)) ?
in_reply[i]->name : in_reply[i]->filename, sizeof(name));
this->Send_GRFIdentifier(packet, in_reply[i]);
NetworkSend_string(packet, name);
this->Send_GRFIdentifier(&packet, in_reply[i]);
NetworkSend_string(&packet, name);
}
this->SendPacket(packet, client_addr);
free(packet);
this->SendPacket(&packet, client_addr);
}
///*** Communication with servers (we are client) ***/
@ -313,18 +306,17 @@ DEF_UDP_RECEIVE_COMMAND(Client, PACKET_UDP_SERVER_RESPONSE)
if (in_request_count > 0) {
/* There are 'unknown' GRFs, now send a request for them */
uint i;
Packet *packet = NetworkSend_Init(PACKET_UDP_CLIENT_GET_NEWGRFS);
Packet packet(PACKET_UDP_CLIENT_GET_NEWGRFS);
NetworkSend_uint8 (packet, in_request_count);
NetworkSend_uint8 (&packet, in_request_count);
for (i = 0; i < in_request_count; i++) {
this->Send_GRFIdentifier(packet, in_request[i]);
this->Send_GRFIdentifier(&packet, in_request[i]);
}
out_addr.sin_family = AF_INET;
out_addr.sin_port = htons(item->port);
out_addr.sin_addr.s_addr = item->ip;
this->SendPacket(packet, &out_addr);
free(packet);
this->SendPacket(&packet, &out_addr);
}
}
@ -436,10 +428,10 @@ void NetworkUDPCloseAll(void)
// Broadcast to all ips
static void NetworkUDPBroadCast(NetworkUDPSocketHandler *socket)
{
Packet* p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
uint i;
for (i = 0; _broadcast_list[i] != 0; i++) {
Packet p(PACKET_UDP_CLIENT_FIND_SERVER);
struct sockaddr_in out_addr;
out_addr.sin_family = AF_INET;
@ -448,10 +440,8 @@ static void NetworkUDPBroadCast(NetworkUDPSocketHandler *socket)
DEBUG(net, 4, "[udp] broadcasting to %s", inet_ntoa(out_addr.sin_addr));
socket->SendPacket(p, &out_addr);
socket->SendPacket(&p, &out_addr);
}
free(p);
}
@ -459,26 +449,23 @@ static void NetworkUDPBroadCast(NetworkUDPSocketHandler *socket)
void NetworkUDPQueryMasterServer(void)
{
struct sockaddr_in out_addr;
Packet *p;
if (!_udp_client_socket->IsConnected()) {
if (!_udp_client_socket->Listen(0, 0, true)) return;
}
p = NetworkSend_Init(PACKET_UDP_CLIENT_GET_LIST);
Packet p(PACKET_UDP_CLIENT_GET_LIST);
out_addr.sin_family = AF_INET;
out_addr.sin_port = htons(NETWORK_MASTER_SERVER_PORT);
out_addr.sin_addr.s_addr = NetworkResolveHost(NETWORK_MASTER_SERVER_HOST);
// packet only contains protocol version
NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
NetworkSend_uint8(&p, NETWORK_MASTER_SERVER_VERSION);
_udp_client_socket->SendPacket(p, &out_addr);
_udp_client_socket->SendPacket(&p, &out_addr);
DEBUG(net, 2, "[udp] master server queried at %s:%d", inet_ntoa(out_addr.sin_addr),ntohs(out_addr.sin_port));
free(p);
DEBUG(net, 2, "[udp] master server queried at %s:%d", inet_ntoa(out_addr.sin_addr), ntohs(out_addr.sin_port));
}
// Find all servers
@ -501,7 +488,6 @@ void NetworkUDPSearchGame(void)
NetworkGameList *NetworkUDPQueryServer(const char* host, unsigned short port)
{
struct sockaddr_in out_addr;
Packet *p;
NetworkGameList *item;
// No UDP-socket yet..
@ -521,11 +507,8 @@ NetworkGameList *NetworkUDPQueryServer(const char* host, unsigned short port)
item->online = false;
// Init the packet
p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
_udp_client_socket->SendPacket(p, &out_addr);
free(p);
Packet p(PACKET_UDP_CLIENT_FIND_SERVER);
_udp_client_socket->SendPacket(&p, &out_addr);
UpdateNetworkGameWindow(false);
return item;
@ -535,7 +518,6 @@ NetworkGameList *NetworkUDPQueryServer(const char* host, unsigned short port)
void NetworkUDPRemoveAdvertise(void)
{
struct sockaddr_in out_addr;
Packet *p;
/* Check if we are advertising */
if (!_networking || !_network_server || !_network_udp_server) return;
@ -553,13 +535,11 @@ void NetworkUDPRemoveAdvertise(void)
out_addr.sin_addr.s_addr = NetworkResolveHost(NETWORK_MASTER_SERVER_HOST);
/* Send the packet */
p = NetworkSend_Init(PACKET_UDP_SERVER_UNREGISTER);
Packet p(PACKET_UDP_SERVER_UNREGISTER);
/* Packet is: Version, server_port */
NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
NetworkSend_uint16(p, _network_server_port);
_udp_master_socket->SendPacket(p, &out_addr);
free(p);
NetworkSend_uint8 (&p, NETWORK_MASTER_SERVER_VERSION);
NetworkSend_uint16(&p, _network_server_port);
_udp_master_socket->SendPacket(&p, &out_addr);
}
/* Register us to the master server
@ -567,7 +547,6 @@ void NetworkUDPRemoveAdvertise(void)
void NetworkUDPAdvertise(void)
{
struct sockaddr_in out_addr;
Packet *p;
/* Check if we should send an advertise */
if (!_networking || !_network_server || !_network_udp_server || !_network_advertise)
@ -604,14 +583,12 @@ void NetworkUDPAdvertise(void)
DEBUG(net, 1, "[udp] advertising to master server");
/* Send the packet */
p = NetworkSend_Init(PACKET_UDP_SERVER_REGISTER);
Packet p(PACKET_UDP_SERVER_REGISTER);
/* Packet is: WELCOME_MESSAGE, Version, server_port */
NetworkSend_string(p, NETWORK_MASTER_SERVER_WELCOME_MESSAGE);
NetworkSend_uint8(p, NETWORK_MASTER_SERVER_VERSION);
NetworkSend_uint16(p, _network_server_port);
_udp_master_socket->SendPacket(p, &out_addr);
free(p);
NetworkSend_string(&p, NETWORK_MASTER_SERVER_WELCOME_MESSAGE);
NetworkSend_uint8 (&p, NETWORK_MASTER_SERVER_VERSION);
NetworkSend_uint16(&p, _network_server_port);
_udp_master_socket->SendPacket(&p, &out_addr);
}
void NetworkUDPInitialize(void)