|
reSIProcate/rutil
9694
|
00001 #ifndef STUN_HXX 00002 #define STUN_HXX 00003 00004 #include <iostream> 00005 #include <time.h> 00006 #include "rutil/Data.hxx" 00007 #include "rutil/Socket.hxx" 00008 00009 // if you change this version, change in makefile too 00010 #define STUN_VERSION "0.96" 00011 00012 #define STUN_MAX_STRING 256 00013 #define STUN_MAX_UNKNOWN_ATTRIBUTES 8 00014 #define STUN_MAX_MESSAGE_SIZE 2048 00015 00016 #define STUN_PORT 3478 00017 00018 #ifndef RESIP_COMPAT_HXX 00019 // define some basic types 00020 typedef unsigned char UInt8; 00021 typedef unsigned short UInt16; 00022 #ifdef __APPLE__ 00023 typedef unsigned long UInt32; 00024 #else 00025 typedef unsigned int UInt32; 00026 #endif 00027 #if defined( WIN32 ) 00028 typedef unsigned __int64 UInt64; 00029 #else 00030 typedef unsigned long long UInt64; 00031 #endif 00032 #endif 00033 00034 typedef struct { unsigned char octet[16]; } UInt128; 00035 00036 #ifdef __cplusplus 00037 bool operator<(const UInt128&, const UInt128&); 00038 bool operator==(const UInt128&, const UInt128&); 00039 #endif 00040 00042 const UInt8 IPv4Family = 0x01; 00043 const UInt8 IPv6Family = 0x02; 00044 00045 // define flags 00046 const UInt32 ChangeIpFlag = 0x04; 00047 const UInt32 ChangePortFlag = 0x02; 00048 00049 // define stun attribute 00050 const UInt16 MappedAddress = 0x0001; 00051 const UInt16 ResponseAddress = 0x0002; 00052 const UInt16 ChangeRequest = 0x0003; 00053 const UInt16 SourceAddress = 0x0004; 00054 const UInt16 ChangedAddress = 0x0005; 00055 const UInt16 Username = 0x0006; 00056 const UInt16 Password = 0x0007; 00057 const UInt16 MessageIntegrity = 0x0008; 00058 const UInt16 ErrorCode = 0x0009; 00059 const UInt16 UnknownAttribute = 0x000A; 00060 const UInt16 ReflectedFrom = 0x000B; 00061 const UInt16 XorMappedAddress = 0x8020; 00062 const UInt16 XorOnly = 0x0021; 00063 const UInt16 ServerName = 0x8022; 00064 const UInt16 SecondaryAddress = 0x8050; // Non standard extention 00065 00066 // !jf! TURN specific message attributes - from turn-08 00067 const UInt16 TurnLifetime = 0x000d; 00068 const UInt16 TurnAlternateServer = 0x000e; 00069 const UInt16 TurnMagicCookie = 0x000f; 00070 const UInt16 TurnBandwidth = 0x0010; 00071 const UInt16 TurnDestinationAddress = 0x0011; 00072 const UInt16 TurnRemoteAddress = 0x0012; 00073 const UInt16 TurnData = 0x0013; 00074 const UInt16 TurnNonce = 0x0014; 00075 const UInt16 TurnRealm = 0x0015; 00076 00077 00078 // define types for a stun message 00079 const UInt16 BindRequestMsg = 0x0001; 00080 const UInt16 BindResponseMsg = 0x0101; 00081 const UInt16 BindErrorResponseMsg = 0x0111; 00082 const UInt16 SharedSecretRequestMsg = 0x0002; 00083 const UInt16 SharedSecretResponseMsg = 0x0102; 00084 const UInt16 SharedSecretErrorResponseMsg = 0x0112; 00085 00086 // define types for a turn message - per turn-08 00087 const UInt16 TurnAllocateRequest = 0x0003; 00088 const UInt16 TurnAllocateResponse = 0x0103; 00089 const UInt16 TurnAllocateErrorResponse = 0x0113; 00090 const UInt16 TurnSendRequest = 0x0004; 00091 const UInt16 TurnSendResponse = 0x0104; 00092 const UInt16 TurnSendErrorResponse = 0x0114; 00093 const UInt16 TurnDataIndication = 0x0115; 00094 const UInt16 TurnSetActiveDestinationRequest = 0x0006; 00095 const UInt16 TurnSetActiveDestinationResponse = 0x0106; 00096 const UInt16 TurnSetActiveDestinationErrorResponse = 0x0116; 00097 00098 typedef struct 00099 { 00100 UInt16 msgType; 00101 UInt16 msgLength; 00102 UInt128 id; 00103 } StunMsgHdr; 00104 00105 #ifdef __cplusplus 00106 bool operator<(const StunMsgHdr&, const StunMsgHdr&); 00107 #endif 00108 00109 typedef struct 00110 { 00111 UInt16 type; 00112 UInt16 length; 00113 } StunAtrHdr; 00114 00115 typedef struct 00116 { 00117 UInt16 port; 00118 UInt32 addr; 00119 } StunAddress4; 00120 00121 typedef struct 00122 { 00123 UInt8 pad; 00124 UInt8 family; 00125 StunAddress4 ipv4; 00126 } StunAtrAddress4; 00127 00128 typedef struct 00129 { 00130 UInt32 value; 00131 } StunAtrChangeRequest; 00132 00133 typedef struct 00134 { 00135 UInt16 pad; // all 0 00136 UInt8 errorClass; 00137 UInt8 number; 00138 char reason[STUN_MAX_STRING]; 00139 UInt16 sizeReason; 00140 } StunAtrError; 00141 00142 typedef struct 00143 { 00144 UInt16 attrType[STUN_MAX_UNKNOWN_ATTRIBUTES]; 00145 UInt16 numAttributes; 00146 } StunAtrUnknown; 00147 00148 typedef struct 00149 { 00150 char value[STUN_MAX_STRING]; 00151 UInt16 sizeValue; 00152 } StunAtrString; 00153 00154 typedef struct 00155 { 00156 char hash[20]; 00157 } StunAtrIntegrity; 00158 00159 00160 enum StunHmacStatus 00161 { 00162 HmacUnknown=0, 00163 HmacOK, 00164 HmacBadUserName, 00165 HmacUnknownUserName, 00166 HmacFailed 00167 }; 00168 00169 00170 typedef struct 00171 { 00172 StunMsgHdr msgHdr; 00173 00174 bool hasMappedAddress; 00175 StunAtrAddress4 mappedAddress; 00176 00177 bool hasResponseAddress; 00178 StunAtrAddress4 responseAddress; 00179 00180 bool hasChangeRequest; 00181 StunAtrChangeRequest changeRequest; 00182 00183 bool hasSourceAddress; 00184 StunAtrAddress4 sourceAddress; 00185 00186 bool hasChangedAddress; 00187 StunAtrAddress4 changedAddress; 00188 00189 bool hasUsername; 00190 StunAtrString username; 00191 00192 bool hasPassword; 00193 StunAtrString password; 00194 00195 bool hasMessageIntegrity; 00196 StunAtrIntegrity messageIntegrity; 00197 00198 bool hasErrorCode; 00199 StunAtrError errorCode; 00200 00201 bool hasUnknownAttributes; 00202 StunAtrUnknown unknownAttributes; 00203 00204 bool hasReflectedFrom; 00205 StunAtrAddress4 reflectedFrom; 00206 00207 bool hasXorMappedAddress; 00208 StunAtrAddress4 xorMappedAddress; 00209 00210 bool xorOnly; 00211 00212 bool hasServerName; 00213 StunAtrString serverName; 00214 00215 bool hasSecondaryAddress; 00216 StunAtrAddress4 secondaryAddress; 00217 00218 bool hasTurnLifetime; 00219 UInt32 turnLifetime; 00220 00221 bool hasTurnAlternateServer; 00222 StunAtrAddress4 turnAlternateServer; 00223 00224 bool hasTurnMagicCookie; 00225 UInt32 turnMagicCookie; 00226 00227 bool hasTurnBandwidth; 00228 UInt32 turnBandwidth; 00229 00230 bool hasTurnDestinationAddress; 00231 StunAtrAddress4 turnDestinationAddress; 00232 00233 bool hasTurnRemoteAddress; 00234 StunAtrAddress4 turnRemoteAddress; 00235 00236 bool hasTurnData; 00237 resip::Data* turnData; 00238 00239 //bool hasTurnNonce; 00240 // turnNonce; 00241 00242 //bool hasTurnRealm; 00243 // turnRealm; 00244 } StunMessage; 00245 00246 00247 // Define enum with different types of NAT 00248 enum NatType 00249 { 00250 StunTypeUnknown=0, 00251 StunTypeFailure, 00252 StunTypeOpen, 00253 StunTypeBlocked, 00254 00255 StunTypeIndependentFilter, 00256 StunTypeDependentFilter, 00257 StunTypePortDependedFilter, 00258 StunTypeDependentMapping, 00259 00260 //StunTypeConeNat, 00261 //StunTypeRestrictedNat, 00262 //StunTypePortRestrictedNat, 00263 //StunTypeSymNat, 00264 00265 StunTypeFirewall 00266 }; 00267 00268 00269 #define MAX_MEDIA_RELAYS 500 00270 #define MAX_RTP_MSG_SIZE 1500 00271 #define MEDIA_RELAY_TIMEOUT 3*60 00272 00273 typedef struct 00274 { 00275 int relayPort; // media relay port 00276 int fd; // media relay file descriptor 00277 StunAddress4 destination; // NAT IP:port 00278 time_t expireTime; // if no activity after time, close the socket 00279 } StunMediaRelay; 00280 00281 typedef struct 00282 { 00283 StunAddress4 myAddr; 00284 StunAddress4 altAddr; 00285 resip::Socket myFd; 00286 resip::Socket altPortFd; 00287 resip::Socket altIpFd; 00288 resip::Socket altIpPortFd; 00289 bool relay; // true if media relaying is to be done 00290 StunMediaRelay relays[MAX_MEDIA_RELAYS]; 00291 } StunServerInfo; 00292 00293 bool 00294 stunParseMessage( char* buf, 00295 unsigned int bufLen, 00296 StunMessage& message, 00297 bool verbose ); 00298 00299 void 00300 stunBuildReqSimple( StunMessage* msg, 00301 const StunAtrString& username, 00302 bool changePort, bool changeIp, unsigned int id=0 ); 00303 00304 unsigned int 00305 stunEncodeMessage( const StunMessage& message, 00306 char* buf, 00307 unsigned int bufLen, 00308 const StunAtrString& password, 00309 bool verbose); 00310 00311 void 00312 stunCreateUserName(const StunAddress4& addr, StunAtrString* username); 00313 00314 void 00315 stunGetUserNameAndPassword( const StunAddress4& dest, 00316 StunAtrString* username, 00317 StunAtrString* password); 00318 00319 void 00320 stunCreatePassword(const StunAtrString& username, StunAtrString* password); 00321 00322 int 00323 stunRand(); 00324 00325 UInt64 00326 stunGetSystemTimeSecs(); 00327 00329 bool 00330 stunParseServerName( char* serverName, StunAddress4& stunServerAddr); 00331 00332 bool 00333 stunParseHostName( char* peerName, 00334 UInt32& ip, 00335 UInt16& portVal, 00336 UInt16 defaultPort ); 00337 00340 bool 00341 stunInitServer(StunServerInfo& info, 00342 const StunAddress4& myAddr, 00343 const StunAddress4& altAddr, 00344 int startMediaPort, 00345 bool verbose); 00346 00347 void 00348 stunStopServer(StunServerInfo& info); 00349 00351 bool 00352 stunServerProcess(StunServerInfo& info, bool verbose); 00353 00355 int 00356 stunFindLocalInterfaces(UInt32* addresses, int maxSize ); 00357 00358 bool 00359 stunTest( StunAddress4& dest, int testNum, bool verbose, StunAddress4* srcAddr=0, unsigned long timeoutMs=5000 ); 00360 00361 NatType 00362 stunNatType( StunAddress4& dest, bool verbose, 00363 bool* preservePort=0, // if set, is return for if NAT preservers ports or not 00364 bool* hairpin=0 , // if set, is the return for if NAT will hairpin packets 00365 int port=0, // port to use for the test, 0 to choose random port 00366 StunAddress4* sAddr=0 // NIC to use 00367 ); 00368 00370 std::ostream& 00371 operator<<( std::ostream& strm, const StunAddress4& addr); 00372 00373 std::ostream& 00374 operator<< ( std::ostream& strm, const UInt128& ); 00375 00376 std::ostream& 00377 operator<< ( std::ostream& strm, const StunMsgHdr& ); 00378 00379 bool 00380 stunServerProcessMsg( char* buf, 00381 unsigned int bufLen, 00382 StunAddress4& from, 00383 StunAddress4& secondary, 00384 StunAddress4& myAddr, 00385 StunAddress4& altAddr, 00386 StunMessage* resp, 00387 StunAddress4* destination, 00388 StunAtrString* hmacPassword, 00389 bool* changePort, 00390 bool* changeIp, 00391 bool verbose); 00392 00393 int 00394 stunOpenSocket( StunAddress4& dest, 00395 StunAddress4* mappedAddr, 00396 int port=0, 00397 StunAddress4* srcAddr=0, 00398 bool verbose=false ); 00399 00400 bool 00401 stunOpenSocketPair( StunAddress4& dest, StunAddress4* mappedAddr, 00402 int* fd1, int* fd2, 00403 int srcPort=0, StunAddress4* srcAddr=0, 00404 bool verbose=false); 00405 00406 int 00407 stunRandomPort(); 00408 00409 void computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey); 00410 00411 #endif 00412 00413 00414 /* ==================================================================== 00415 * The Vovida Software License, Version 1.0 00416 * 00417 * Redistribution and use in source and binary forms, with or without 00418 * modification, are permitted provided that the following conditions 00419 * are met: 00420 * 00421 * 1. Redistributions of source code must retain the above copyright 00422 * notice, this list of conditions and the following disclaimer. 00423 * 00424 * 2. Redistributions in binary form must reproduce the above copyright 00425 * notice, this list of conditions and the following disclaimer in 00426 * the documentation and/or other materials provided with the 00427 * distribution. 00428 * 00429 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00430 * and "Vovida Open Communication Application Library (VOCAL)" must 00431 * not be used to endorse or promote products derived from this 00432 * software without prior written permission. For written 00433 * permission, please contact vocal@vovida.org. 00434 * 00435 * 4. Products derived from this software may not be called "VOCAL", nor 00436 * may "VOCAL" appear in their name, without prior written 00437 * permission of Vovida Networks, Inc. 00438 * 00439 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00440 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00441 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00442 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00443 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00444 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00445 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00446 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00447 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00448 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00449 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00450 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00451 * DAMAGE. 00452 * 00453 */ 00454 00455 // Local Variables: 00456 // mode:c++ 00457 // c-file-style:"ellemtel" 00458 // c-file-offsets:((case-label . +)) 00459 // indent-tabs-mode:nil 00460 // End: 00461
1.7.5.1