sP2P c++ STL *nix API  1.2
NAT traversal and peer-to-peer networking API providing all utilities needed to build peer-to-peer application straigth out of box
 All Classes Functions Variables Typedefs Enumerations Enumerator
stun.h
1 /*
2 #################################################################################################
3 # sP2P NAT Traversal/Peer-To-Peer networking API
4 #
5 # This file is part of comercial product. You can not use it in any way, redistribute it
6 # in any way and/or modify it in any way unless you get right to do so.
7 #
8 # Use licence can only be acquired from:
9 # ---------------------------------------------------
10 # AS-CAL,raziskave in razvoj, d.o.o.
11 # Kongresni trg 9, 1000 Ljubljana - Slovenia
12 # Company ID: 3913147000
13 # ---------------------------------------------------
14 # , or product legal successor.
15 #
16 #################################################################################################
17 # Ivan Milic
18 # HOLEST Engineering
19 # www.holest.com
20 # Belgrade, Serbia
21 # January, 2013
22 ##################################################################################################
23 */
24 
25 
26 
27 #ifndef STUN_H
28 #define STUN_H
29 
30 #define STUN_MAX_STRING 256
31 #define STUN_MAX_UNKNOWN_ATTRIBUTES 8
32 #define STUN_MAX_MESSAGE_SIZE 2048
33 #define STUN_PORT 3478
34 
35 
36 #include "Common.h"
37 #include "IPEndPoint.h"
38 #include "Uninetwork.h"
39 #include <list>
40 #include <map>
41 #include <set>
42 
43 namespace sp2plib{
44 
45 class SP2P_API STUN{
46 public:
47 
49  typedef enum NAT_Type
50  {
52  NAT_UdpBlocked = 0,
53 
57  NAT_OpenInternet = 255,
58 
62  NAT_SymmetricUdpFirewall = 20,
63 
69  NAT_FullCone = 200,
70 
77  NAT_RestrictedCone = 150,
78 
85  NAT_PortRestrictedCone = 100,
86 
94  NAT_Symmetric = 50,
95 
99  NAT_Unknown = 10
100  } NAT_Type;
101 
103  struct StunResponse{
104  NAT_Type NATType;
105  IPEndPoint ReflectedEndPoint;
106  ::std::list<sp2plib::UInt16> MappedPorts;
107  ~StunResponse(){
108  MappedPorts.clear();
109  /*if(this->MappedPorts != NULL){
110  delete this->MappedPorts;
111  }*/
112  }
113  };
114 
120  static StunResponse Query(Socket sock, char* host, sp2plib::UInt16 port = STUN_PORT , sp2plib::UInt16 StunResponseTimeout = 450);
121 
127  static StunResponse Query(Socket sock, IP4Address srvAddr, sp2plib::UInt16 port = STUN_PORT , sp2plib::UInt16 StunResponseTimeout = 450);
128 
135  static int PortQuery(::std::map< ::std::string,IPEndPoint> *result, Socket s, IPEndPoint stunEP, int maxWait = 2000);
136 
143  static int PortQueryUniquePorts(::std::set<sp2plib::UInt16> *result, Socket s, IPEndPoint stunEP, int maxWait = 2000);
144 
147  static ::std::string NATTypeName(NAT_Type NType);
148 
149 private:
150 
151 typedef enum StunAttributeType {
152  SAT_MappedAddress = 0x0001,
153  SAT_ResponseAddress = 0x0002,
154  SAT_ChangeRequest = 0x0003,
155  SAT_SourceAddress = 0x0004,
156  SAT_ChangedAddress = 0x0005,
157  SAT_Username = 0x0006,
158  SAT_Password = 0x0007,
159  SAT_MessageIntegrity = 0x0008,
160  SAT_ErrorCode = 0x0009,
161  SAT_UnknownAttribute = 0x000A,
162  SAT_ReflectedFrom = 0x000B,
163  SAT_XorMappedAddress = 0x8020,
164  SAT_XorOnly = 0x0021,
165  SAT_ServerName = 0x8022,
166  SAT_SecondaryAddress = 0x8050
167 } StunAttributeType;
168 
169 typedef enum StunMessageType {
170  SMT_BindRequestMsg = 0x0001,
171  SMT_BindResponseMsg = 0x0101,
172  SMT_BindErrorResponseMsg = 0x0111,
173  SMT_SharedSecretRequestMsg = 0x0002,
174  SMT_SharedSecretResponseMsg = 0x0102,
175  SMT_SharedSecretErrorResponseMsg = 0x0112
176 } StunMessageType;
177 
178 typedef struct
179 {
180  sp2plib::UInt16 Type;//StunMessageType
181  sp2plib::UInt16 Length;
182  sp2plib::UInt128 ID;
183 } StunMessageHeader;
184 
185 
186 typedef struct
187 {
188  sp2plib::UInt16 Type;//StunAttributeType
189  sp2plib::UInt16 Length;
190 } StunAttributeHeader;
191 
192 
193 typedef struct
194 {
195  sp2plib::UInt8 pad;
196  sp2plib::UInt8 family;
197  IPEndPoint EndPoint;
198 } StunAttributeAddress;
199 
200 typedef struct
201 {
202  sp2plib::UInt32 value;
203 } StunAttributeChangeRequest;
204 
205 typedef struct
206 {
207  sp2plib::UInt16 pad; // all 0
208  sp2plib::UInt8 errorClass;
209  sp2plib::UInt8 number;
210  char reason[STUN_MAX_STRING];
211  sp2plib::UInt16 sizeReason;
212 } StunAttributeError;
213 
214 typedef struct
215 {
216  sp2plib::UInt16 attrType[STUN_MAX_UNKNOWN_ATTRIBUTES];
217  sp2plib::UInt16 numAttributes;
218 } StunAttributeUnknown;
219 
220 typedef struct
221 {
222  char value[STUN_MAX_STRING];
223  sp2plib::UInt16 sizeValue;
224 } StunAttributeString;
225 
226 typedef struct
227 {
228  StunMessageHeader Header;
229 
230  bool hasMappedAddress;
231  StunAttributeAddress mappedAddress;
232 
233  bool hasResponseAddress;
234  StunAttributeAddress responseAddress;
235 
236  bool hasChangeRequest;
237  StunAttributeChangeRequest changeRequest;
238 
239  bool hasSourceAddress;
240  StunAttributeAddress sourceAddress;
241 
242  bool hasChangedAddress;
243  StunAttributeAddress changedAddress;
244 
245  bool hasUsername;
246  StunAttributeString username;
247 
248  bool hasPassword;
249  StunAttributeString password;
250 
251  bool hasErrorCode;
252  StunAttributeError errorCode;
253 
254  bool hasUnknownAttributes;
255  StunAttributeUnknown unknownAttributes;
256 
257  bool hasReflectedFrom;
258  StunAttributeAddress reflectedFrom;
259 
260  bool hasXorMappedAddress;
261  StunAttributeAddress xorMappedAddress;
262 
263  bool xorOnly;
264 
265  bool hasServerName;
266  StunAttributeString serverName;
267 
268  bool hasSecondaryAddress;
269  StunAttributeAddress secondaryAddress;
270 } StunMessage;
271 
272 
273 static const sp2plib::UInt32 ChangeIpFlag = 0x04;
274 static const sp2plib::UInt32 ChangePortFlag = 0x02;
275 static const sp2plib::UInt8 IPv4Family = 0x01;
276 static const sp2plib::UInt8 IPv6Family = 0x02;
277 static const int HeaderSize = 20;
278 
279 
280 static StunMessage * new_DoTransaction(StunMessage * request, Socket sock, IPEndPoint *ServerEndPoint,sp2plib::UInt16 StunResponseTimeout);
281 static char* encode16(char* buf, sp2plib::UInt16 data);
282 static char* encode32(char* buf, sp2plib::UInt32 data);
283 static char* encode(char* buf, const char* data, unsigned int length);
284 static char* encodeAddress(char* ptr, sp2plib::UInt16 type,StunAttributeAddress Attribute);
285 static char* encodeChangeRequest(char* ptr, StunAttributeChangeRequest Attribute );
286 static char* encodeError(char* ptr, StunAttributeError Attribute);
287 static char* encodeUnknown(char* ptr, StunAttributeUnknown Attribute);
288 static char* encodeXorOnly(char* ptr);
289 static char* encodeString(char* ptr, sp2plib::UInt16 type, StunAttributeString Attribute);
290 static unsigned int serializeMessage( const StunMessage &message,
291  char* buff,
292  unsigned int buffLength,
293  const StunAttributeString *password = NULL
294  );
295 static bool ParseAddress( char* body, unsigned int headerLen, StunAttributeAddress &result );
296 static bool ParseChangeRequest( char* body, unsigned int headerLen, StunAttributeChangeRequest &result );
297 static bool ParseError( char* body, unsigned int headerLen, StunAttributeError &result );
298 static bool ParseUnknown( char* body, unsigned int headerLen, StunAttributeUnknown &result );
299 static bool ParseString( char* body, unsigned int headerLen, StunAttributeString &result );
300 static bool ParseMessage( char* buff, unsigned int buffLength, StunMessage& message);
301 static bool CreateRequest( StunMessage* message, bool changePort, bool changeIp, sp2plib::UInt128 *ID = NULL);
302 
303 };
304 
305 }
306 
307 #endif