oRTP  0.16.1
stun.h
1  /*
2  The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack.
3  Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library 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 GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 
20 /* ====================================================================
21  * The Vovida Software License, Version 1.0
22  *
23  * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
24  *
25  * Redistribution and use in source and binary forms, with or without
26  * modification, are permitted provided that the following conditions
27  * are met:
28  *
29  * 1. Redistributions of source code must retain the above copyright
30  * notice, this list of conditions and the following disclaimer.
31  *
32  * 2. Redistributions in binary form must reproduce the above copyright
33  * notice, this list of conditions and the following disclaimer in
34  * the documentation and/or other materials provided with the
35  * distribution.
36  *
37  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
38  * and "Vovida Open Communication Application Library (VOCAL)" must
39  * not be used to endorse or promote products derived from this
40  * software without prior written permission. For written
41  * permission, please contact vocal@vovida.org.
42  *
43  * 4. Products derived from this software may not be called "VOCAL", nor
44  * may "VOCAL" appear in their name, without prior written
45  * permission of Vovida Networks, Inc.
46  *
47  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
48  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
50  * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
51  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
52  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
53  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
54  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
55  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
56  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
57  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
58  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
59  * DAMAGE.
60  *
61  * ====================================================================
62  *
63  * This software consists of voluntary contributions made by Vovida
64  * Networks, Inc. and many individuals on behalf of Vovida Networks,
65  * Inc. For more information on Vovida Networks, Inc., please see
66  * <http://www.vovida.org/>.
67  *
68  */
69 
70 
71 #ifndef __STUN_H__
72 #define __STUN_H__
73 
74 #include <stdio.h>
75 #include <time.h>
76 #include <ortp/port.h>
77 #include <ortp/stun_udp.h>
78 
79 
80 #ifdef __cplusplus
81 extern "C"
82 {
83 #endif
84 
85 /* if you change this version, change in makefile too */
86 #define STUN_VERSION "0.99"
87 
88 #define STUN_MAX_STRING 256
89 #define STUN_MAX_UNKNOWN_ATTRIBUTES 8
90 #define STUN_MAX_MESSAGE_SIZE 2048
91 
92 #define STUN_PORT 3478
93 
94 /* define some basic types */
95 typedef unsigned char UInt8;
96 typedef unsigned short UInt16;
97 typedef unsigned int UInt32;
98 #if defined(WIN32) || defined(_WIN32_WCE)
99 typedef unsigned __int64 UInt64;
100 #else
101 typedef unsigned long long UInt64;
102 #endif
103 typedef struct { unsigned char octet[12]; } UInt96;
104 
105 /* define a structure to hold a stun address */
106 #define IPv4Family 0x01
107 #define IPv6Family 0x02
108 
109 /* define flags */
110 #define ChangeIpFlag 0x04
111 #define ChangePortFlag 0x02
112 
113 /* define stun attribute */
114 #define SA_MAPPEDADDRESS 0x0001
115 #define SA_RESPONSEADDRESS 0x0002
116 #define SA_CHANGEREQUEST 0x0003
117 #define SA_SOURCEADDRESS 0x0004
118 #define SA_CHANGEDADDRESS 0x0005
119 #define SA_USERNAME 0x0006
120 #define SA_PASSWORD 0x0007
121 #define SA_MESSAGEINTEGRITY 0x0008
122 #define SA_ERRORCODE 0x0009
123 #define SA_UNKNOWNATTRIBUTE 0x000A
124 #define SA_REFLECTEDFROM 0x000B
125 #define SA_REALM 0x0014
126 #define SA_NONCE 0x0015
127 #define SA_XORMAPPEDADDRESS 0x0020
128 
129 #define SA_XORMAPPEDADDRESS2 0x8020 /* Non standard extention */
130 #define SA_XORONLY 0x0021 /* deprecated */
131 #define SA_SECONDARYADDRESS 0x0050 /* Non standard extention */
132 
133 #define SA_SOFTWARE 0x8022
134 #define SA_ALTERNATESERVER 0x8023
135 #define SA_FINGERPRINT 0x8028
136 
137 /* define turn attribute */
138 #define TA_CHANNELNUMBER 0x000C
139 #define TA_LIFETIME 0x000D
140 #define TA_DEPRECATEDBANDWIDTH 0x0010
141 #define TA_XORPEERADDRESS 0x0012
142 #define TA_DATA 0x0013
143 #define TA_XORRELAYEDADDRESS 0x0016
144 #define TA_EVENPORT 0x0018
145 #define TA_REQUESTEDTRANSPORT 0x0019
146 #define TA_DONTFRAGMENT 0x001A
147 #define TA_DEPRECATEDTIMERVAL 0x0021
148 #define TA_RESERVATIONTOKEN 0x0022
149 
150 #define ICEA_PRIORITY 0x0024
151 #define ICEA_USECANDIDATE 0x0025
152 #define ICEA_ICECONTROLLED 0x8029
153 #define ICEA_ICECONTROLLING 0x802a
154 
155 #define STUN_REQUEST 0x0000
156 #define STUN_INDICATION 0x0010
157 #define STUN_SUCCESS_RESP 0x0100
158 #define STUN_ERR_RESP 0x0110
159 
160 #define STUN_IS_REQUEST(msg_type) (((msg_type) & 0x0110) == 0x0000)
161 #define STUN_IS_INDICATION(msg_type) (((msg_type) & 0x0110) == 0x0010)
162 #define STUN_IS_SUCCESS_RESP(msg_type) (((msg_type) & 0x0110) == 0x0100)
163 #define STUN_IS_ERR_RESP(msg_type) (((msg_type) & 0x0110) == 0x0110)
164 
165 /* define types for a stun message */
166 #define STUN_METHOD_BINDING 0x0001
167 #define TURN_MEDHOD_ALLOCATE 0x0003 //(only request/response semantics defined)
168 #define TURN_METHOD_REFRESH 0x0004 //(only request/response semantics defined)
169 #define TURN_METHOD_CREATEPERMISSION 0x0008 //(only request/response semantics defined
170 #define TURN_METHOD_CHANNELBIND 0x0009 //(only request/response semantics defined)
171 
172 //#define BindResponseMsg 0x0101
173 //#define BindErrorResponseMsg 0x0111
174 #define SharedSecretRequestMsg 0x0002
175 #define SharedSecretResponseMsg 0x0102
176 #define SharedSecretErrorResponseMsg 0x0112
177 
178 #define TURN_INDICATION_SEND 0x0006 //(only indication semantics defined)
179 #define TURN_INDICATION_DATA 0x0007 //(only indication semantics defined)
180 
181 typedef struct
182 {
183  UInt16 msgType;
184  UInt16 msgLength;
185  UInt32 magic_cookie;
186  UInt96 tr_id;
187 } StunMsgHdr;
188 
189 
190 typedef struct
191 {
192  UInt16 type;
193  UInt16 length;
194 } StunAtrHdr;
195 
196 typedef struct
197 {
198  UInt16 port;
199  UInt32 addr;
200 } StunAddress4;
201 
202 typedef struct
203 {
204  UInt8 pad;
205  UInt8 family;
206  StunAddress4 ipv4;
208 
209 typedef struct
210 {
211  UInt32 value;
213 
214 typedef struct
215 {
216  UInt16 pad; /* all 0 */
217  UInt8 errorClass;
218  UInt8 number;
219  char reason[STUN_MAX_STRING];
220  UInt16 sizeReason;
221 } StunAtrError;
222 
223 typedef struct
224 {
225  UInt16 attrType[STUN_MAX_UNKNOWN_ATTRIBUTES];
226  UInt16 numAttributes;
228 
229 typedef struct
230 {
231  UInt16 channelNumber;
232  UInt16 rffu; /* Reserved For Future Use */
234 
235 typedef struct
236 {
237  UInt32 lifetime;
239 
240 typedef struct
241 {
242  char value[1500];
243  UInt16 sizeValue;
244 } TurnAtrData;
245 
246 typedef struct
247 {
248  UInt8 proto;
249  UInt8 pad1;
250  UInt8 pad2;
251  UInt8 pad3;
253 
254 typedef struct
255 {
256  UInt64 value;
258 
259 typedef struct
260 {
261  UInt32 fingerprint;
263 
264 
265 typedef struct
266 {
267  char value[STUN_MAX_STRING];
268  UInt16 sizeValue;
269 } StunAtrString;
270 
271 typedef struct
272 {
273  UInt32 priority;
275 
276 typedef struct
277 {
278  UInt64 value;
280 
281 typedef struct
282 {
283  char hash[20];
285 
286 typedef enum
287 {
288  HmacUnkown=0,
289  HmacOK,
290  HmacBadUserName,
291  HmacUnkownUserName,
292  HmacFailed
293 } StunHmacStatus;
294 
295 
296 typedef struct
297 {
298  UInt16 attrType[STUN_MAX_UNKNOWN_ATTRIBUTES];
299  UInt16 numAttributes;
301 
302 typedef struct
303 {
304  StunMsgHdr msgHdr;
305 
306  bool_t hasMappedAddress;
307  StunAtrAddress4 mappedAddress;
308 
309  bool_t hasResponseAddress;
310  StunAtrAddress4 responseAddress;
311 
312  bool_t hasChangeRequest;
313  StunAtrChangeRequest changeRequest;
314 
315  bool_t hasSourceAddress;
316  StunAtrAddress4 sourceAddress;
317 
318  bool_t hasChangedAddress;
319  StunAtrAddress4 changedAddress;
320 
321  bool_t hasUsername;
322  StunAtrString username;
323 
324  bool_t hasPassword;
325  StunAtrString password;
326 
327  bool_t hasMessageIntegrity;
328  StunAtrIntegrity messageIntegrity;
329 
330  bool_t hasErrorCode;
331  StunAtrError errorCode;
332 
333  bool_t hasUnknownAttributes;
334  StunAtrUnknown unknownAttributes;
335 
336  bool_t hasReflectedFrom;
337  StunAtrAddress4 reflectedFrom;
338 
339  bool_t hasRealm;
340  StunAtrString realmName;
341 
342  bool_t hasNonce;
343  StunAtrString nonceName;
344 
345  bool_t hasXorMappedAddress;
346  StunAtrAddress4 xorMappedAddress;
347 
348  bool_t hasSoftware;
349  StunAtrString softwareName;
350 
351  bool_t hasXorPeerAddress;
352  StunAtrAddress4 xorPeerAddress;
353 
354  bool_t hasXorRelayedAddress;
355  StunAtrAddress4 xorRelayedAddress;
356 
357  bool_t hasFingerprint;
358  StunAtrFingerprint fingerprint;
359 
360  /* Turn elements */
361  bool_t hasChannelNumberAttributes;
362  TurnAtrChannelNumber channelNumberAttributes;
363 
364  bool_t hasLifetimeAttributes;
365  TurnAtrLifetime lifetimeAttributes;
366 
367  bool_t hasData;
368  TurnAtrData data;
369 
370  bool_t hasRequestedTransport;
371  TurnAtrRequestedTransport requestedTransport;
372 
373  bool_t hasDontFragment;
374 
375  bool_t hasReservationToken;
376  TurnAtrReservationToken reservationToken;
377 
378  bool_t hasPriority;
379  IceAtrPriority priority;
380 
381  bool_t hasUseCandidate;
382 
383  bool_t hasIceControlled;
384  IceAtrIceControll iceControlled;
385 
386  bool_t hasIceControlling;
387  IceAtrIceControll iceControlling;
388 } StunMessage;
389 
390 
391 /* Define enum with different types of NAT */
392 typedef enum
393 {
394  StunTypeUnknown=0,
395  StunTypeOpen,
396  StunTypeConeNat,
397  StunTypeRestrictedNat,
398  StunTypePortRestrictedNat,
399  StunTypeSymNat,
400  StunTypeSymFirewall,
401  StunTypeBlocked,
402  StunTypeFailure
403 } NatType;
404 
405 
406 #define MAX_MEDIA_RELAYS 500
407 #define MAX_RTP_MSG_SIZE 1500
408 #define MEDIA_RELAY_TIMEOUT 3*60
409 
410 typedef struct
411 {
412  int relayPort; /* media relay port */
413  int fd; /* media relay file descriptor */
414  StunAddress4 destination; /* NAT IP:port */
415  time_t expireTime; /* if no activity after time, close the socket */
417 
418 typedef struct
419 {
420  StunAddress4 myAddr;
421  StunAddress4 altAddr;
422  Socket myFd;
423  Socket altPortFd;
424  Socket altIpFd;
425  Socket altIpPortFd;
426  bool_t relay; /* true if media relaying is to be done */
427  StunMediaRelay relays[MAX_MEDIA_RELAYS];
429 
430 void
431 stunCalculateIntegrity_longterm(char* hmac, const char* input, int length,
432  const char *username, const char *realm, const char *password);
433 void
434 stunCalculateIntegrity_shortterm(char* hmac, const char* input, int length, const char* key);
435 UInt32
436 stunCalculateFingerprint(const char* input, int length);
437 
438 bool_t
439 stunParseMessage( char* buf,
440  unsigned int bufLen,
441  StunMessage *message);
442 
443 void
444 stunBuildReqSimple( StunMessage* msg,
445  const StunAtrString *username,
446  bool_t changePort, bool_t changeIp, unsigned int id );
447 
448 unsigned int
449 stunEncodeMessage( const StunMessage *message,
450  char* buf,
451  unsigned int bufLen,
452  const StunAtrString *password);
453 
454 void
455 stunCreateUserName(const StunAddress4 *addr, StunAtrString* username);
456 
457 void
458 stunGetUserNameAndPassword( const StunAddress4 *dest,
459  StunAtrString* username,
460  StunAtrString* password);
461 
462 void
463 stunCreatePassword(const StunAtrString *username, StunAtrString* password);
464 
465 int
466 stunRand(void);
467 
468 UInt64
469 stunGetSystemTimeSecs(void);
470 
471 /* find the IP address of a the specified stun server - return false is fails parse */
472 bool_t
473 stunParseServerName( const char* serverName, StunAddress4 *stunServerAddr);
474 
475 bool_t
476 stunParseHostName( const char* peerName,
477  UInt32 *ip,
478  UInt16 *portVal,
479  UInt16 defaultPort );
480 
481 /* return true if all is OK
482  Create a media relay and do the STERN thing if startMediaPort is non-zero */
483 bool_t
484 stunInitServer(StunServerInfo *info,
485  const StunAddress4 *myAddr,
486  const StunAddress4 *altAddr,
487  int startMediaPort);
488 
489 void
490 stunStopServer(StunServerInfo *info);
491 
492 /* returns number of address found - take array or addres */
493 int
494 stunFindLocalInterfaces(UInt32* addresses, int maxSize );
495 
496 int
497 stunTest( StunAddress4 *dest, int testNum, StunAddress4* srcAddr, StunAddress4 *sMappedAddr, StunAddress4* sChangedAddr);
498 
499 NatType
500 stunNatType( StunAddress4 *dest,
501  bool_t* preservePort, /* if set, is return for if NAT preservers ports or not */
502  bool_t* hairpin , /* if set, is the return for if NAT will hairpin packets */
503  int port, /* port to use for the test, 0 to choose random port */
504  StunAddress4* sAddr /* NIC to use */
505  );
506 
507 bool_t
508 stunServerProcessMsg( char* buf,
509  unsigned int bufLen,
510  StunAddress4 *from,
511  StunAddress4 *myAddr,
512  StunAddress4 *altAddr,
513  StunMessage *resp,
514  StunAddress4 *destination,
515  StunAtrString *hmacPassword,
516  bool_t* changePort,
517  bool_t* changeIp);
518 
519 int
520 stunOpenSocket( StunAddress4 *dest,
521  StunAddress4* mappedAddr,
522  int port,
523  StunAddress4* srcAddr);
524 
525 bool_t
526 stunOpenSocketPair(StunAddress4 *dest,
527  StunAddress4* mapAddr_rtp,
528  StunAddress4* mapAddr_rtcp,
529  int* fd1, int* fd2,
530  int srcPort, StunAddress4* srcAddr);
531 
532 bool_t
533 turnAllocateSocketPair(StunAddress4 *dest,
534  StunAddress4* mapAddr_rtp,
535  StunAddress4* mapAddr_rtcp,
536  int* fd1, int* fd2,
537  int srcPort, StunAddress4* srcAddr);
538 
539 #ifdef __cplusplus
540 }
541 #endif
542 
543 #endif
544