Planeshift
netpacket.h
Go to the documentation of this file.
1 /*
2  * netpacket.h
3  *
4  * Copyright (C) 2001 Atomic Blue (info@planeshift.it, http://www.atomicblue.org)
5  *
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation (version 2 of the License)
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  *
18  */
19 #ifndef __NETPACKET_H__
20 #define __NETPACKET_H__
21 
22 #include <csutil/csendian.h>
23 #include <csutil/refcount.h>
24 #include <csutil/hash.h>
25 
26 #include "net/packing.h"
27 #include "net/message.h"
28 
33 enum
34 {
35  PKTSIZE_ACK = 0, // 0 pktsize means ACK pkt
36  PKTMINRTO = 250, // Minimum of 250 mseconds till packet resend
37  PKTMAXRTO = 60000, // Maximum of 1 minute till packet resend
38  PKTINITRTO = 3000, // Initially assume 3 seconds till packet resend
39  FLAG_MULTIPACKET = 0x02, // priority bit 1 is multipacket on/off
41  MAXPACKETSIZE = 1400 // 1400 bytes is max size of network packet
42 };
43 
54 #pragma pack(1)
56 {
61  uint32_t pktid;
62 
66  uint32_t offset;
67  uint32_t msgsize;
68  uint16_t pktsize;
69 
72  uint8_t flags;
73 
75  char data[0];
76 
77 
78  size_t GetPacketSize() const
79  {
80  if (pktsize == PKTSIZE_ACK)
81  return sizeof(psNetPacket);
82  else
83  return sizeof(psNetPacket) + pktsize;
84  };
85 
86  bool IsMultiPacket() const
87  {
88  return (flags & FLAG_MULTIPACKET)? true: false;
89  }
90 
91  uint8_t GetPriority() const
92  {
93  return flags & PRIORITY_MASK;
94  }
95 
96  uint8_t GetSequence() const
97  {
98  return flags>>2; // upper 6 bits of flags should be sequence id
99  }
100 
101  void MarshallEndian() {
102  // Pack up for transmission. This endian-izes the packet.
103  pktid = csLittleEndian::Convert((uint32)pktid);
104  offset = csLittleEndian::Convert((uint32)offset);
105  msgsize = csLittleEndian::Convert((uint32)msgsize);
106  pktsize = csLittleEndian::Convert((uint16)pktsize);
107  }
108 
110  // Unpack from transmission. This deendian-izes the packet.
111  pktid = csLittleEndian::UInt32(pktid);
112  offset = csLittleEndian::UInt32(offset);
113  msgsize = csLittleEndian::UInt32(msgsize);
114  pktsize = csLittleEndian::UInt16(pktsize);
115  }
116 
117  /* The goal here is to verify fields that later parsing can't.
118  * Specifically we need to make sure the buffer can hold at least the
119  * fields that must be present in every packet, and also that the reported
120  * packet length is less than or equal to the data provided in the buffer.
121  * (Really it should be the same length, but extra won't cause us to crash)
122  */
123  static struct psNetPacket *NetPacketFromBuffer(void *buffer,int buffer_length)
124  {
125  if ( !buffer )
126  return NULL;
127 
128  struct psNetPacket *potentialpacket;
129 
130  if (buffer_length < (int)sizeof(struct psNetPacket))
131  return NULL; // Buffer data too short for even the header
132 
133  potentialpacket=(struct psNetPacket *)buffer;
134 
135  if ((unsigned int)buffer_length < csLittleEndian::Convert(potentialpacket->pktsize) + sizeof(struct psNetPacket))
136  return NULL; // Buffer data too short for the packet length reported in the header
137 
138  return potentialpacket;
139  }
140 
141 };
142 #pragma pack()
143 
144 
145 //-----------------------------------------------------------------------------
146 
147 
149 {
150  uint32_t clientnum;
151  uint32_t pktid;
152 public:
153  PacketKey(uint32_t Clientnum, uint32_t Pktid):clientnum(Clientnum), pktid(Pktid) { };
154 
155  bool operator < (const PacketKey& other) const
156  {
157  if (clientnum < other.clientnum)
158  return true;
159  if (clientnum > other.clientnum)
160  return false;
161 
162  return (pktid < other.pktid);
163  };
164 };
165 
166 
167 //-----------------------------------------------------------------------------
168 
169 
170 template<> class csHashComputer<PacketKey> : public csHashComputerStruct<PacketKey>
171 {
172 };
173 
174 
175 //-----------------------------------------------------------------------------
176 
177 
179 {
180 public:
182  uint32_t clientnum;
183 
184  csTicks timestamp;
185 
188 
190  csTicks RTO;
191 
196 
200  psNetPacketEntry (psNetPacket* packet, uint32_t cnum, uint16_t sz);
201 
203  psNetPacketEntry (uint8_t pri, uint32_t cnum, uint32_t id,
204  uint32_t off, uint32_t totalsize, uint16_t sz,
205  psMessageBytes *msg);
206 
208  psNetPacketEntry (uint8_t pri, uint32_t cnum,
209  uint32_t id, uint32_t off, uint32_t totalsize, uint16_t sz,
210  const char *bytes);
211 
213  {
214  CS_ASSERT(false);
215  }
216 
217  ~psNetPacketEntry();
218 
219  bool Append(psNetPacketEntry* next);
220  csPtr<psNetPacketEntry> GetNextPacket(psNetPacket* &packetdata);
221 
222 
223  void* GetData()
224  {
225  return packet;
226  }
227 
228  bool operator < (const psNetPacketEntry& other) const
229  {
230  if (clientnum < other.clientnum)
231  return true;
232  if (clientnum > other.clientnum)
233  return false;
234 
235  if (packet->pktid < other.packet->pktid)
236  return true;
237  if (packet->pktid > other.packet->pktid)
238  return false;
239 
240  if (packet->offset < other.packet->offset)
241  return true;
242 
243  return false;
244  };
245 
247  // Dummy functions required by GenericQueue
249  void SetPending(bool /*flag*/)
250  { }
251  bool GetPending()
252  { return false; }
253 };
254 
255 
256 //-----------------------------------------------------------------------------
257 
258 
259 template<>
260 class csComparator<csRef<psNetPacketEntry> , csRef<psNetPacketEntry> >
261 {
262 public:
263  static int Compare(csRef<psNetPacketEntry> const &r1, csRef<psNetPacketEntry> const &r2)
264  {
265  return csComparator<psNetPacketEntry, psNetPacketEntry>::Compare(*r1, *r2);
266  }
267 };
268 
271 #endif
272 
void UnmarshallEndian()
Definition: netpacket.h:109
static struct psNetPacket * NetPacketFromBuffer(void *buffer, int buffer_length)
Definition: netpacket.h:123
psNetPacket * packet
The Packet like it is returned from reading UDP socket / will be written to socket.
Definition: netpacket.h:195
psNetPacketEntry(psNetPacketEntry *)
Definition: netpacket.h:212
csTicks RTO
timeout
Definition: netpacket.h:190
size_t GetPacketSize() const
Definition: netpacket.h:78
uint32_t msgsize
Definition: netpacket.h:67
uint16_t pktsize
Definition: netpacket.h:68
uint8_t GetPriority() const
Definition: netpacket.h:91
uint32_t pktid
each packet must know what message it&#39;s a part of this should be 0 in most cases as it&#39;s assigned at ...
Definition: netpacket.h:61
void MarshallEndian()
Definition: netpacket.h:101
uint32_t clientnum
clientnum this packet comes from/goes to
Definition: netpacket.h:182
csTicks timestamp
Definition: netpacket.h:184
MAXPACKETSIZE includes header length ( sizeof(struct psNetPacket) )
Definition: netpacket.h:41
psNetPacket gives the networking code the context it needs, and all of this info goes out on the wire...
Definition: netpacket.h:55
bool retransmitted
has this packet been retransmitted
Definition: netpacket.h:187
uint8_t GetSequence() const
Definition: netpacket.h:96
void SetPending(bool)
Definition: netpacket.h:249
bool IsMultiPacket() const
Definition: netpacket.h:86
uint8_t flags
Each packet needs to know its own priority.
Definition: netpacket.h:72
bool GetPending()
Definition: netpacket.h:251
char data[0]
this can be used as a pointer to the data
Definition: netpacket.h:75
bool operator<(long lhs, const GmpInt &rhs)
Definition: GmpInt.h:135
PacketKey(uint32_t Clientnum, uint32_t Pktid)
Definition: netpacket.h:153
uint32_t offset
offset and size together specify a memory block within the psMessageBytes struct
Definition: netpacket.h:66
static int Compare(csRef< psNetPacketEntry > const &r1, csRef< psNetPacketEntry > const &r2)
Definition: netpacket.h:263
this struct represents the data that is sent out through the network (all additional stuff should go ...
Definition: message.h:111
void * GetData()
Definition: netpacket.h:223