Spinning Topp Logo BlackTopp Studios
inc
packet.h
1 // © Copyright 2010 - 2016 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 
41 #ifndef _networkpacket_h
42 #define _networkpacket_h
43 
44 #include "datatypes.h"
45 
46 namespace Mezzanine
47 {
48  namespace Network
49  {
50  ///////////////////////////////////////////////////////////////////////////////
51  /// @brief A base class for packing information to be transferred over the network.
52  /// @remarks Notes about Packets and Fragmentation: @n
53  /// When creating packets for any application there should be size considerations. Routers are permitted to fragment
54  /// any packet that it cannot send along to the destination host due to hardware limitations that exist along the path
55  /// the packet is taking. There are some exceptions to this. In the IPv4 options a flag can be set to disable
56  /// fragmentation performed by routers. In the event that a packet would be fragmented with the flag present the packet
57  /// will be dropped and an error sent back saying it couldn't be delivered. In IPv6 fragmentation simply cannot happen;
58  /// it is disabled as per the IPv6 specification and packets are dropped and an error sent back just like with the IPv4
59  /// flag. The error sent back in both cases is often manifested as "Destination Unreachable". @n
60  /// So it is important to know how big of a transmission is supported between the local host and the remote host to
61  /// facilitate error-free and IP agnostic transmissions, or to just avoid fragmentation altogether that could generate
62  /// odd errors if one fragment goes missing. This is primarily a concern for UDP, which is a "fire-and-forget" protocol
63  /// without any redundancy. However it can still be useful to know for TCP for making some optimizations. The big terms
64  /// in relation to all of this are MTU(Maximum Transmission Unit) and MSS(Maximum Segment Size). MTU is the maximum total
65  /// size of a packet without fragmentation that exists between two hosts. MSS is very closely related to the MTU and
66  /// relates specifically to TCP; it is the maximum size of a single segment of a TCP stream. @n
67  /// I mentioned hardware limitations earlier. Each piece of internetworking equipment can and likely will implement their
68  /// own MTU. So the MTU is highly variable, even when connecting to the same host if it happens to choose a different
69  /// path(which can happen even for something simple as the return trip on the same connection). The more internetworking
70  /// devices you encounter the most likely you are to encounter a device with a low MTU. This is double true for devices
71  /// that exist on networks you can't control (I.E. the internet). Fortunately there are some standards in place that help
72  /// us out. @n
73  /// There are two things to keep in mind regarding standards relating to MTU, on is the standards relating to the actual
74  /// MTU to be set, and the "minimum maximum reassembly buffer size" that must be set that determines the ideal MTU for a
75  /// given device. IETF RFC 1122 states the minimum MTU for IPv4 must be 68. Likewise, IETF RFC 1122 states the minimum
76  /// MTU for IPv6 is 1280. Both of these standards go on to specify their reassembly buffer sizes to be at least 576 and
77  /// 1500, respectively. These numbers are the recommended minimums for MTU on any connected device. While these numbers
78  /// may be low, they are also the highest that can be expected among devices encountered on the internet. Real world MTU
79  /// can be higher and likely will be in some cases, but there is no hard and fast rules for that. So the numbers for the
80  /// IPv4 and IPv6 reassembly buffers will be our sane defaults prior to any actual detection along a path between
81  /// connected hosts. @n
82  /// So we have the total size of a transmission, but we're not quite set just yet. There are headers created by the OS
83  /// upon transmission of any given message that take up space in the packet. So we must take the size of the headers and
84  /// subtract that from the values mentioned above. Both layer 3 and layer 4 protocols have packet headers that count
85  /// against us here. Most of them also have options so their headers are somewhat of a variable length. The UDP is the
86  /// most straightforward, with an 8 byte header and no available options. TCP is a bit more complicated with a 40 byte
87  /// header and depending on options can be up to an additional 40 bytes. In other words the bulkiest TCP header is 10
88  /// times the size of any UDP header! But still 80 bytes isn't too bad, especially not when you are working with a
89  /// reliable protocol such as TCP. IPv4 and IPv6 is where things get a little weirder. IPv4 has a simple 20 byte header
90  /// and it's options can by up to 40 bytes on top of that, tripling it's size. The IPv6 header is 40 bytes large, and it's
91  /// options are...complicated. IPv6 changed the packet format so in the core header it defines the next header, which
92  /// could be a higher protocol header (such as TCP or UDP) or one of it's options. Each option header has an identical
93  /// field with information on it's offsets. So options don't have a fixed layout, or really a fixed size, and can be
94  /// chained for quite some length. Unlike the other options values, using the max is just too large and too unrealistic
95  /// to factor in. Instead 40 bytes of space for possible options is a sane value to set aside. @n
96  /// The static members that exist on the Packet class exist to help facilitate this math and provide constants to compare
97  /// to when creating a message to be packed into a packet. These values are meant to represent sane defaults to keep your
98  /// packets under (in size) in order to avoid delivery complications for transmissions. It is entirely possible, even
99  /// common, for you to be able to sent packets larger than these sizes without experiencing any issues. This could be
100  /// as simple as the options fields for the packets sent aren't used, or the MTU between you and the remote host is much
101  /// larger than what is expected here. In situations where you need to send a transmission larger than the static values
102  /// given in those constants, then the MTU should be tested before arbitrarily packing more data into your packets. Also
103  /// keep in mind that these values are intended for internet transmissions, and transmissions over LAN can and will have a
104  /// much large MTU in nearly all cases. Regardless, testing is valuable.
105  /// @todo Update this with information on how to manually detect the MTU between local and remote hosts.
106  ///////////////////////////////////////
108  {
109  public:
110  ///////////////////////////////////////////////////////////////////////////////
111  // Public Static Data Members
112 
113  /// @brief The maximum size an entire single transmission can be without fragmenting/rejection over IPv4.
114  static const Whole DefaultIPv4MTU;
115  /// @brief The maximum size an entire single transmission can be without fragmenting/rejection over IPv6.
116  static const Whole DefaultIPv6MTU;
117  /// @brief The maximum size the message portion of a UDP packet can be without fragmenting/rejection with IPv4.
119  /// @brief The maximum size the message portion of a UDP packet can be without being rejected with IPv6.
121  /// @brief The maximum size the message portion of a TCP packet can be without segmenting with IPv4.
123  /// @brief The maximum size the message portion of a TCP packet can be without segmenting with IPv6.
125 
126  ///////////////////////////////////////////////////////////////////////////////
127  // Construction and Destruction
128 
129  /// @brief Class constructor.
130  Packet();
131  /// @brief Class destructor.
132  virtual ~Packet();
133 
134  ///////////////////////////////////////////////////////////////////////////////
135  // Utility
136 
137  /// @brief Gets the type of packet.
138  /// @return Returns a UInt15 that is the type ID of this packet.
139  virtual UInt16 GetPacketType() const = 0;
140  /// @brief Gets the size this packet should be according to it's type.
141  /// @return Returns the size this packet should be based on it's type ID in bytes.
142  virtual Whole GetExpectedSize() const = 0;
143 
144  /// @brief Gets the actual size of this packet.
145  /// @return Returns the current size of the buffer in this packet.
146  virtual Whole GetSize() const = 0;
147  /// @brief Gets whether or not this packet is the size it should be.
148  /// @return Returns true if this packet is the size that is expected for it's type, false otherwise.
149  Boole IsExpectedSize() const;
150 
151  ///////////////////////////////////////////////////////////////////////////////
152  // Buffer Management
153 
154  /// @brief Sets the raw data in this packet.
155  /// @param Buffer The data to be set.
156  /// @param BufSize The size of the buffer being set.
157  virtual void SetData(const void* Buffer, const Whole BufSize) = 0;
158  /// @brief Appends additional content onto this packet.
159  /// @param Buffer The data to be appended.
160  /// @param BufSize The size of the buffer being appended.
161  virtual void AppendData(const void* Buffer, const Whole BufSize) = 0;
162  /// @brief Gets the raw data of this packet.
163  /// @return Returns a void pointer to the internal buffer for this packet.
164  virtual void* GetData() = 0;
165  /// @brief Gets the raw data of this packet.
166  /// @return Returns a void pointer to the internal buffer for this packet.
167  virtual const void* GetData() const = 0;
168  /// @brief Clears or resets the contents of this packet.
169  virtual void ClearData() = 0;
170  };//Packet
171  }//Network
172 }//Mezzanine
173 
174 #endif
static const Whole DefaultUDPv6MsgSize
The maximum size the message portion of a UDP packet can be without being rejected with IPv6...
Definition: packet.h:120
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
static const Whole DefaultTCPv6MsgSize
The maximum size the message portion of a TCP packet can be without segmenting with IPv6...
Definition: packet.h:124
static const Whole DefaultIPv4MTU
The maximum size an entire single transmission can be without fragmenting/rejection over IPv4...
Definition: packet.h:114
All the definitions for datatypes as well as some basic conversion functions are defined here...
static const Whole DefaultTCPv4MsgSize
The maximum size the message portion of a TCP packet can be without segmenting with IPv4...
Definition: packet.h:122
uint16_t UInt16
An 16-bit unsigned integer.
Definition: datatypes.h:122
A base class for packing information to be transferred over the network.
Definition: packet.h:107
static const Whole DefaultUDPv4MsgSize
The maximum size the message portion of a UDP packet can be without fragmenting/rejection with IPv4...
Definition: packet.h:118
#define MEZZ_LIB
Some platforms require special decorations to denote what is exported/imported in a share library...
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
Definition: datatypes.h:151
static const Whole DefaultIPv6MTU
The maximum size an entire single transmission can be without fragmenting/rejection over IPv6...
Definition: packet.h:116