oRTP 0.16.5
include/ortp/stun.h
00001  /*
00002   The oRTP library is an RTP (Realtime Transport Protocol - rfc3550) stack.
00003   Copyright (C) 2001  Simon MORLAT simon.morlat@linphone.org
00004 
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Lesser General Public
00007   License as published by the Free Software Foundation; either
00008   version 2.1 of the License, or (at your option) any later version.
00009 
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Lesser General Public License for more details.
00014 
00015   You should have received a copy of the GNU Lesser General Public
00016   License along with this library; if not, write to the Free Software
00017   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 */
00019 
00020 /* ====================================================================
00021  * The Vovida Software License, Version 1.0 
00022  * 
00023  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00024  * 
00025  * Redistribution and use in source and binary forms, with or without
00026  * modification, are permitted provided that the following conditions
00027  * are met:
00028  * 
00029  * 1. Redistributions of source code must retain the above copyright
00030  *    notice, this list of conditions and the following disclaimer.
00031  * 
00032  * 2. Redistributions in binary form must reproduce the above copyright
00033  *    notice, this list of conditions and the following disclaimer in
00034  *    the documentation and/or other materials provided with the
00035  *    distribution.
00036  * 
00037  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00038  *    and "Vovida Open Communication Application Library (VOCAL)" must
00039  *    not be used to endorse or promote products derived from this
00040  *    software without prior written permission. For written
00041  *    permission, please contact vocal@vovida.org.
00042  *
00043  * 4. Products derived from this software may not be called "VOCAL", nor
00044  *    may "VOCAL" appear in their name, without prior written
00045  *    permission of Vovida Networks, Inc.
00046  * 
00047  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00048  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00049  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00050  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00051  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00052  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00053  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00054  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00055  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00056  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00057  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00058  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00059  * DAMAGE.
00060  * 
00061  * ====================================================================
00062  * 
00063  * This software consists of voluntary contributions made by Vovida
00064  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00065  * Inc.  For more information on Vovida Networks, Inc., please see
00066  * <http://www.vovida.org/>.
00067  *
00068  */
00069 
00070 
00071 #ifndef __STUN_H__
00072 #define __STUN_H__
00073 
00074 #include <stdio.h>
00075 #include <time.h>
00076 #include <ortp/port.h>
00077 #include <ortp/stun_udp.h>
00078 
00079 #ifdef __APPLE__
00080    #include "TargetConditionals.h"
00081 #endif
00082 
00083 #ifdef __cplusplus
00084 extern "C"
00085 {
00086 #endif
00087 
00088 /* if you change this version, change in makefile too  */
00089 #define STUN_VERSION "0.99"
00090 
00091 #define STUN_MAX_STRING 256
00092 #define STUN_MAX_UNKNOWN_ATTRIBUTES 8
00093 #define STUN_MAX_MESSAGE_SIZE 2048
00094 
00095 #define STUN_PORT 3478
00096 
00097 /* define some basic types */
00098 #if 0
00099 typedef unsigned char  uint8_t;
00100 typedef unsigned short uint16_t;
00101 typedef unsigned int   uint32_t;
00102 
00103 #if     defined(WIN32) || defined(_WIN32_WCE)
00104 typedef unsigned __int64 uint64_t;
00105 #else
00106 typedef unsigned long long uint64_t;
00107 #endif
00108 #endif
00109 typedef struct { unsigned char octet[12]; }  UInt96;
00110 
00111 /* define a structure to hold a stun address  */
00112 #define  IPv4Family  0x01
00113 #define  IPv6Family  0x02
00114 
00115 /* define  flags  */
00116 #define ChangeIpFlag    0x04
00117 #define ChangePortFlag  0x02
00118 
00119 /* define  stun attribute */
00120 #define SA_MAPPEDADDRESS     0x0001
00121 #define SA_RESPONSEADDRESS   0x0002 
00122 #define SA_CHANGEREQUEST     0x0003 
00123 #define SA_SOURCEADDRESS     0x0004 
00124 #define SA_CHANGEDADDRESS    0x0005 
00125 #define SA_USERNAME          0x0006
00126 #define SA_PASSWORD          0x0007  
00127 #define SA_MESSAGEINTEGRITY  0x0008
00128 #define SA_ERRORCODE         0x0009
00129 #define SA_UNKNOWNATTRIBUTE  0x000A
00130 #define SA_REFLECTEDFROM     0x000B 
00131 #define SA_REALM             0x0014
00132 #define SA_NONCE             0x0015
00133 #define SA_XORMAPPEDADDRESS  0x0020
00134 
00135 #define SA_XORMAPPEDADDRESS2 0x8020 /* Non standard extention */
00136 #define SA_XORONLY           0x0021 /* deprecated */
00137 #define SA_SECONDARYADDRESS  0x0050 /* Non standard extention */
00138 
00139 #define SA_SOFTWARE          0x8022
00140 #define SA_ALTERNATESERVER   0x8023
00141 #define SA_FINGERPRINT       0x8028
00142 
00143 /* define turn attribute */
00144 #define TA_CHANNELNUMBER       0x000C
00145 #define TA_LIFETIME            0x000D
00146 #define TA_DEPRECATEDBANDWIDTH 0x0010
00147 #define TA_XORPEERADDRESS      0x0012
00148 #define TA_DATA                0x0013
00149 #define TA_XORRELAYEDADDRESS   0x0016
00150 #define TA_EVENPORT            0x0018
00151 #define TA_REQUESTEDTRANSPORT  0x0019
00152 #define TA_DONTFRAGMENT        0x001A
00153 #define TA_DEPRECATEDTIMERVAL  0x0021
00154 #define TA_RESERVATIONTOKEN    0x0022
00155 
00156 #define ICEA_PRIORITY          0x0024
00157 #define ICEA_USECANDIDATE      0x0025
00158 #define ICEA_ICECONTROLLED     0x8029
00159 #define ICEA_ICECONTROLLING    0x802a
00160 
00161 #define STUN_REQUEST           0x0000
00162 #define STUN_INDICATION        0x0010
00163 #define STUN_SUCCESS_RESP      0x0100
00164 #define STUN_ERR_RESP          0x0110
00165 
00166 #define STUN_IS_REQUEST(msg_type)       (((msg_type) & 0x0110) == 0x0000)
00167 #define STUN_IS_INDICATION(msg_type)    (((msg_type) & 0x0110) == 0x0010)
00168 #define STUN_IS_SUCCESS_RESP(msg_type)  (((msg_type) & 0x0110) == 0x0100)
00169 #define STUN_IS_ERR_RESP(msg_type)      (((msg_type) & 0x0110) == 0x0110)
00170 
00171 /* define types for a stun message */
00172 #define STUN_METHOD_BINDING           0x0001
00173 #define TURN_MEDHOD_ALLOCATE          0x0003 //(only request/response semantics defined)
00174 #define TURN_METHOD_REFRESH           0x0004 //(only request/response semantics defined)
00175 #define TURN_METHOD_CREATEPERMISSION  0x0008 //(only request/response semantics defined
00176 #define TURN_METHOD_CHANNELBIND       0x0009 //(only request/response semantics defined)
00177 
00178 //#define BindResponseMsg               0x0101
00179 //#define BindErrorResponseMsg          0x0111
00180 #define SharedSecretRequestMsg        0x0002
00181 #define SharedSecretResponseMsg       0x0102
00182 #define SharedSecretErrorResponseMsg  0x0112
00183 
00184 #define TURN_INDICATION_SEND          0x0006 //(only indication semantics defined)
00185 #define TURN_INDICATION_DATA          0x0007 //(only indication semantics defined)
00186 
00187 typedef struct 
00188 {
00189       uint16_t msgType;
00190       uint16_t msgLength;
00191       uint32_t magic_cookie;
00192       UInt96 tr_id;
00193 } StunMsgHdr;
00194 
00195 
00196 typedef struct
00197 {
00198       uint16_t type;
00199       uint16_t length;
00200 } StunAtrHdr;
00201 
00202 typedef struct
00203 {
00204       uint16_t port;
00205       uint32_t addr;
00206 } StunAddress4;
00207 
00208 typedef struct
00209 {
00210       uint8_t pad;
00211       uint8_t family;
00212       StunAddress4 ipv4;
00213 } StunAtrAddress4;
00214 
00215 typedef struct
00216 {
00217       uint32_t value;
00218 } StunAtrChangeRequest;
00219 
00220 typedef struct
00221 {
00222       uint16_t pad; /* all 0 */
00223       uint8_t errorClass;
00224       uint8_t number;
00225       char reason[STUN_MAX_STRING];
00226       uint16_t sizeReason;
00227 } StunAtrError;
00228 
00229 typedef struct
00230 {
00231       uint16_t attrType[STUN_MAX_UNKNOWN_ATTRIBUTES];
00232       uint16_t numAttributes;
00233 } StunAtrUnknown;
00234 
00235 typedef struct
00236 {
00237       uint16_t channelNumber;
00238       uint16_t rffu; /* Reserved For Future Use */
00239 } TurnAtrChannelNumber;
00240 
00241 typedef struct
00242 {
00243       uint32_t lifetime;
00244 } TurnAtrLifetime;
00245 
00246 typedef struct
00247 {
00248       char value[1500];      
00249       uint16_t sizeValue;
00250 } TurnAtrData;
00251 
00252 typedef struct
00253 {
00254       uint8_t proto;
00255       uint8_t pad1;
00256       uint8_t pad2;
00257       uint8_t pad3;
00258 } TurnAtrRequestedTransport;
00259 
00260 typedef struct
00261 {
00262       uint64_t value;
00263 } TurnAtrReservationToken;
00264 
00265 typedef struct
00266 {
00267       uint32_t fingerprint;
00268 } StunAtrFingerprint;
00269 
00270 
00271 typedef struct
00272 {
00273       char value[STUN_MAX_STRING];      
00274       uint16_t sizeValue;
00275 } StunAtrString;
00276 
00277 typedef struct
00278 {
00279       uint32_t priority;
00280 } IceAtrPriority;
00281 
00282 typedef struct
00283 {
00284       uint64_t value;
00285 } IceAtrIceControll;
00286 
00287 typedef struct
00288 {
00289       char hash[20];
00290 } StunAtrIntegrity;
00291 
00292 typedef enum 
00293 {
00294    HmacUnkown=0,
00295    HmacOK,
00296    HmacBadUserName,
00297    HmacUnkownUserName,
00298    HmacFailed
00299 } StunHmacStatus;
00300 
00301 
00302 typedef struct
00303 {
00304       uint16_t attrType[STUN_MAX_UNKNOWN_ATTRIBUTES];
00305       uint16_t numAttributes;
00306 } TurnAtrUnknown;
00307 
00308 typedef struct
00309 {
00310       StunMsgHdr msgHdr;
00311         
00312       bool_t hasMappedAddress;
00313       StunAtrAddress4  mappedAddress;
00314         
00315       bool_t hasResponseAddress;
00316       StunAtrAddress4  responseAddress;
00317         
00318       bool_t hasChangeRequest;
00319       StunAtrChangeRequest changeRequest;
00320         
00321       bool_t hasSourceAddress;
00322       StunAtrAddress4 sourceAddress;
00323         
00324       bool_t hasChangedAddress;
00325       StunAtrAddress4 changedAddress;
00326         
00327       bool_t hasUsername;
00328       StunAtrString username;
00329         
00330       bool_t hasPassword;
00331       StunAtrString password;
00332         
00333       bool_t hasMessageIntegrity;
00334       StunAtrIntegrity messageIntegrity;
00335         
00336       bool_t hasErrorCode;
00337       StunAtrError errorCode;
00338         
00339       bool_t hasUnknownAttributes;
00340       StunAtrUnknown unknownAttributes;
00341         
00342       bool_t hasReflectedFrom;
00343       StunAtrAddress4 reflectedFrom;
00344 
00345       bool_t hasRealm;
00346       StunAtrString realmName;
00347 
00348       bool_t hasNonce;
00349       StunAtrString nonceName;
00350 
00351       bool_t hasXorMappedAddress;
00352       StunAtrAddress4  xorMappedAddress;
00353         
00354       bool_t hasSoftware;
00355       StunAtrString softwareName;
00356 
00357       bool_t hasXorPeerAddress;
00358       StunAtrAddress4 xorPeerAddress;
00359 
00360       bool_t hasXorRelayedAddress;
00361       StunAtrAddress4 xorRelayedAddress;
00362 
00363       bool_t hasFingerprint;
00364       StunAtrFingerprint fingerprint;
00365 
00366       /* Turn elements */
00367       bool_t hasChannelNumberAttributes;
00368       TurnAtrChannelNumber channelNumberAttributes;
00369 
00370       bool_t hasLifetimeAttributes;
00371       TurnAtrLifetime lifetimeAttributes;
00372 
00373       bool_t hasData;
00374       TurnAtrData data;
00375 
00376       bool_t hasRequestedTransport;
00377       TurnAtrRequestedTransport requestedTransport;
00378 
00379       bool_t hasDontFragment;
00380 
00381       bool_t hasReservationToken;
00382       TurnAtrReservationToken reservationToken;
00383 
00384       bool_t hasPriority;
00385       IceAtrPriority priority;
00386 
00387       bool_t hasUseCandidate;
00388 
00389       bool_t hasIceControlled;
00390       IceAtrIceControll iceControlled;
00391 
00392       bool_t hasIceControlling;
00393       IceAtrIceControll iceControlling;
00394 } StunMessage; 
00395 
00396 
00397 /* Define enum with different types of NAT */
00398 typedef enum 
00399 {
00400    StunTypeUnknown=0,
00401    StunTypeOpen,
00402    StunTypeConeNat,
00403    StunTypeRestrictedNat,
00404    StunTypePortRestrictedNat,
00405    StunTypeSymNat,
00406    StunTypeSymFirewall,
00407    StunTypeBlocked,
00408    StunTypeFailure
00409 } NatType;
00410 
00411 
00412 #define MAX_MEDIA_RELAYS 500
00413 #define MAX_RTP_MSG_SIZE 1500
00414 #define MEDIA_RELAY_TIMEOUT 3*60
00415 
00416 typedef struct 
00417 {
00418       int relayPort;       /* media relay port */
00419       int fd;              /* media relay file descriptor */
00420       StunAddress4 destination; /* NAT IP:port */
00421       time_t expireTime;      /* if no activity after time, close the socket */
00422 } StunMediaRelay;
00423 
00424 typedef struct
00425 {
00426       StunAddress4 myAddr;
00427       StunAddress4 altAddr;
00428       Socket myFd;
00429       Socket altPortFd;
00430       Socket altIpFd;
00431       Socket altIpPortFd;
00432       bool_t relay; /* true if media relaying is to be done */
00433       StunMediaRelay relays[MAX_MEDIA_RELAYS];
00434 } StunServerInfo;
00435 
00436 void
00437 stunCalculateIntegrity_longterm(char* hmac, const char* input, int length,
00438                      const char *username, const char *realm, const char *password);
00439 void
00440 stunCalculateIntegrity_shortterm(char* hmac, const char* input, int length, const char* key);
00441 uint32_t
00442 stunCalculateFingerprint(const char* input, int length);
00443 
00444 bool_t
00445 stunParseMessage( char* buf, 
00446                   unsigned int bufLen, 
00447                   StunMessage *message);
00448 
00449 void
00450 stunBuildReqSimple( StunMessage* msg,
00451                     const StunAtrString *username,
00452                     bool_t changePort, bool_t changeIp, unsigned int id );
00453 
00454 unsigned int
00455 stunEncodeMessage( const StunMessage *message, 
00456                    char* buf, 
00457                    unsigned int bufLen, 
00458                    const StunAtrString *password);
00459 
00460 void
00461 stunCreateUserName(const StunAddress4 *addr, StunAtrString* username);
00462 
00463 void 
00464 stunGetUserNameAndPassword(  const StunAddress4 *dest, 
00465                              StunAtrString* username,
00466                              StunAtrString* password);
00467 
00468 void
00469 stunCreatePassword(const StunAtrString *username, StunAtrString* password);
00470 
00471 int 
00472 stunRand(void);
00473 
00474 uint64_t
00475 stunGetSystemTimeSecs(void);
00476 
00477 /* find the IP address of a the specified stun server - return false is fails parse  */
00478 bool_t  
00479 stunParseServerName( const char* serverName, StunAddress4 *stunServerAddr);
00480 
00481 bool_t 
00482 stunParseHostName( const char* peerName,
00483                    uint32_t *ip,
00484                    uint16_t *portVal,
00485                    uint16_t defaultPort );
00486 
00487 /* return true if all is OK 
00488    Create a media relay and do the STERN thing if startMediaPort is non-zero */
00489 bool_t
00490 stunInitServer(StunServerInfo *info, 
00491                const StunAddress4 *myAddr, 
00492                const StunAddress4 *altAddr,
00493                int startMediaPort);
00494 
00495 void
00496 stunStopServer(StunServerInfo *info);
00497 
00498 /* returns number of address found - take array or addres */
00499 int 
00500 stunFindLocalInterfaces(uint32_t* addresses, int maxSize );
00501 
00502 int 
00503 stunTest( StunAddress4 *dest, int testNum, StunAddress4* srcAddr, StunAddress4 *sMappedAddr, StunAddress4* sChangedAddr);
00504 
00505 NatType
00506 stunNatType( StunAddress4 *dest, 
00507              bool_t* preservePort, /* if set, is return for if NAT preservers ports or not */
00508              bool_t* hairpin ,  /* if set, is the return for if NAT will hairpin packets */
00509              int port, /* port to use for the test, 0 to choose random port */
00510              StunAddress4* sAddr /* NIC to use */
00511    );
00512 
00513 bool_t
00514 stunServerProcessMsg( char* buf,
00515                       unsigned int bufLen,
00516                       StunAddress4 *from, 
00517                       StunAddress4 *myAddr,
00518                       StunAddress4 *altAddr, 
00519                       StunMessage *resp,
00520                       StunAddress4 *destination,
00521                       StunAtrString *hmacPassword,
00522                       bool_t* changePort,
00523                       bool_t* changeIp);
00524 
00525 int
00526 stunOpenSocket( StunAddress4 *dest, 
00527                 StunAddress4* mappedAddr, 
00528                 int port, 
00529                 StunAddress4* srcAddr);
00530 
00531 bool_t
00532 stunOpenSocketPair(StunAddress4 *dest,
00533                    StunAddress4* mapAddr_rtp, 
00534                    StunAddress4* mapAddr_rtcp, 
00535                    int* fd1, int* fd2, 
00536                    int srcPort,  StunAddress4* srcAddr);
00537 
00538 bool_t
00539 turnAllocateSocketPair(StunAddress4 *dest,
00540                    StunAddress4* mapAddr_rtp, 
00541                    StunAddress4* mapAddr_rtcp, 
00542                    int* fd1, int* fd2, 
00543                    int srcPort,  StunAddress4* srcAddr);
00544 
00545 #ifdef __cplusplus
00546 }
00547 #endif
00548 
00549 #endif
00550