#include <iostream>
#include <time.h>
Go to the source code of this file.
Classes | |
struct | UInt128 |
struct | StunMsgHdr |
struct | StunAtrHdr |
struct | StunAddress4 |
struct | StunAtrAddress4 |
struct | StunAtrChangeRequest |
struct | StunAtrError |
struct | StunAtrUnknown |
struct | StunAtrString |
struct | StunAtrIntegrity |
struct | StunMessage |
struct | StunMediaRelay |
struct | StunServerInfo |
Defines | |
#define | STUN_VERSION "0.96" |
#define | STUN_MAX_STRING 256 |
#define | STUN_MAX_UNKNOWN_ATTRIBUTES 8 |
#define | STUN_MAX_MESSAGE_SIZE 2048 |
#define | STUN_PORT 3478 |
#define | MAX_MEDIA_RELAYS 500 |
#define | MAX_RTP_MSG_SIZE 1500 |
#define | MEDIA_RELAY_TIMEOUT 3*60 |
Typedefs | |
typedef unsigned char | UInt8 |
typedef unsigned short | UInt16 |
typedef unsigned int | UInt32 |
typedef unsigned long long | UInt64 |
typedef int | Socket |
Enumerations | |
enum | StunHmacStatus { HmacUnkown = 0, HmacOK, HmacBadUserName, HmacUnkownUserName, HmacFailed } |
enum | NatType { StunTypeUnknown = 0, StunTypeFailure, StunTypeOpen, StunTypeBlocked, StunTypeIndependentFilter, StunTypeDependentFilter, StunTypePortDependedFilter, StunTypeDependentMapping, StunTypeFirewall } |
Functions | |
bool | stunParseMessage (char *buf, unsigned int bufLen, StunMessage &message, bool verbose) |
void | stunBuildReqSimple (StunMessage *msg, const StunAtrString &username, bool changePort, bool changeIp, unsigned int id=0) |
unsigned int | stunEncodeMessage (const StunMessage &message, char *buf, unsigned int bufLen, const StunAtrString &password, bool verbose) |
void | stunCreateUserName (const StunAddress4 &addr, StunAtrString *username) |
void | stunGetUserNameAndPassword (const StunAddress4 &dest, StunAtrString *username, StunAtrString *password) |
void | stunCreatePassword (const StunAtrString &username, StunAtrString *password) |
int | stunRand () |
UInt64 | stunGetSystemTimeSecs () |
bool | stunParseServerName (char *serverName, StunAddress4 &stunServerAddr) |
find the IP address of a the specified stun server - return false is fails parse | |
bool | stunParseHostName (char *peerName, UInt32 &ip, UInt16 &portVal, UInt16 defaultPort) |
bool | stunInitServer (StunServerInfo &info, const StunAddress4 &myAddr, const StunAddress4 &altAddr, int startMediaPort, bool verbose) |
return true if all is OK Create a media relay and do the STERN thing if startMediaPort is non-zero | |
void | stunStopServer (StunServerInfo &info) |
bool | stunServerProcess (StunServerInfo &info, bool verbose) |
return true if all is OK | |
int | stunFindLocalInterfaces (UInt32 *addresses, int maxSize) |
returns number of address found - take array or addres | |
void | stunTest (StunAddress4 &dest, int testNum, bool verbose, StunAddress4 *srcAddr=0) |
NatType | stunNatType (StunAddress4 &dest, bool verbose, bool *preservePort=0, bool *hairpin=0, int port=0, StunAddress4 *sAddr=0) |
std::ostream & | operator<< (std::ostream &strm, const StunAddress4 &addr) |
prints a StunAddress | |
std::ostream & | operator<< (std::ostream &strm, const UInt128 &) |
bool | stunServerProcessMsg (char *buf, unsigned int bufLen, StunAddress4 &from, StunAddress4 &myAddr, StunAddress4 &altAddr, StunMessage *resp, StunAddress4 *destination, StunAtrString *hmacPassword, bool *changePort, bool *changeIp, bool verbose) |
int | stunOpenSocket (StunAddress4 &dest, StunAddress4 *mappedAddr, int port=0, StunAddress4 *srcAddr=0, bool verbose=false) |
bool | stunOpenSocketPair (StunAddress4 &dest, StunAddress4 *mappedAddr, int *fd1, int *fd2, int srcPort=0, StunAddress4 *srcAddr=0, bool verbose=false) |
int | stunRandomPort () |
return a random number to use as a port | |
Variables | |
const UInt8 | IPv4Family = 0x01 |
define a structure to hold a stun address | |
const UInt8 | IPv6Family = 0x02 |
const UInt32 | ChangeIpFlag = 0x04 |
const UInt32 | ChangePortFlag = 0x02 |
const UInt16 | MappedAddress = 0x0001 |
const UInt16 | ResponseAddress = 0x0002 |
const UInt16 | ChangeRequest = 0x0003 |
const UInt16 | SourceAddress = 0x0004 |
const UInt16 | ChangedAddress = 0x0005 |
const UInt16 | Username = 0x0006 |
const UInt16 | Password = 0x0007 |
const UInt16 | MessageIntegrity = 0x0008 |
const UInt16 | ErrorCode = 0x0009 |
const UInt16 | UnknownAttribute = 0x000A |
const UInt16 | ReflectedFrom = 0x000B |
const UInt16 | XorMappedAddress = 0x8020 |
const UInt16 | XorOnly = 0x0021 |
const UInt16 | ServerName = 0x8022 |
const UInt16 | SecondaryAddress = 0x8050 |
const UInt16 | BindRequestMsg = 0x0001 |
const UInt16 | BindResponseMsg = 0x0101 |
const UInt16 | BindErrorResponseMsg = 0x0111 |
const UInt16 | SharedSecretRequestMsg = 0x0002 |
const UInt16 | SharedSecretResponseMsg = 0x0102 |
const UInt16 | SharedSecretErrorResponseMsg = 0x0112 |
#define STUN_MAX_STRING 256 |
Definition at line 10 of file stun.h.
Referenced by stunCreateUserName(), stunParseAtrString(), and stunServerProcessMsg().
enum NatType |
StunTypeUnknown | |
StunTypeFailure | |
StunTypeOpen | |
StunTypeBlocked | |
StunTypeIndependentFilter | |
StunTypeDependentFilter | |
StunTypePortDependedFilter | |
StunTypeDependentMapping | |
StunTypeFirewall |
Definition at line 178 of file stun.h.
{ StunTypeUnknown=0, StunTypeFailure, StunTypeOpen, StunTypeBlocked, StunTypeIndependentFilter, StunTypeDependentFilter, StunTypePortDependedFilter, StunTypeDependentMapping, //StunTypeConeNat, //StunTypeRestrictedNat, //StunTypePortRestrictedNat, //StunTypeSymNat, StunTypeFirewall, } NatType;
enum StunHmacStatus |
Definition at line 118 of file stun.h.
{ HmacUnkown=0, HmacOK, HmacBadUserName, HmacUnkownUserName, HmacFailed, } StunHmacStatus;
std::ostream& operator<< | ( | std::ostream & | strm, | |
const StunAddress4 & | addr | |||
) |
prints a StunAddress
std::ostream& operator<< | ( | std::ostream & | strm, | |
const UInt128 & | ||||
) |
void stunBuildReqSimple | ( | StunMessage * | msg, | |
const StunAtrString & | username, | |||
bool | changePort, | |||
bool | changeIp, | |||
unsigned int | id = 0 | |||
) |
Definition at line 1697 of file stun.cc.
Referenced by stunSendTest().
{ assert( msg ); memset( msg , 0 , sizeof(*msg) ); msg->msgHdr.msgType = BindRequestMsg; for ( int i=0; i<16; i=i+4 ) { assert(i+3<16); int r = stunRand(); msg->msgHdr.id.octet[i+0]= r>>0; msg->msgHdr.id.octet[i+1]= r>>8; msg->msgHdr.id.octet[i+2]= r>>16; msg->msgHdr.id.octet[i+3]= r>>24; } if ( id != 0 ) { msg->msgHdr.id.octet[0] = id; } msg->hasChangeRequest = true; msg->changeRequest.value =(changeIp?ChangeIpFlag:0) | (changePort?ChangePortFlag:0); if ( username.sizeValue > 0 ) { msg->hasUsername = true; msg->username = username; } }
void stunCreatePassword | ( | const StunAtrString & | username, | |
StunAtrString * | password | |||
) |
Definition at line 802 of file stun.cc.
Referenced by stunCreateSharedSecretResponse(), stunGetUserNameAndPassword(), and stunServerProcessMsg().
void stunCreateUserName | ( | const StunAddress4 & | addr, | |
StunAtrString * | username | |||
) |
Definition at line 764 of file stun.cc.
Referenced by stunCreateSharedSecretResponse(), and stunGetUserNameAndPassword().
{ UInt64 time = stunGetSystemTimeSecs(); time -= (time % 20*60); //UInt64 hitime = time >> 32; UInt64 lotime = time & 0xFFFFFFFF; char buffer[1024]; sprintf(buffer, "%08x:%08x:%08x:", UInt32(source.addr), UInt32(stunRand()), UInt32(lotime)); assert( strlen(buffer) < 1024 ); assert(strlen(buffer) + 41 < STUN_MAX_STRING); char hmac[20]; char key[] = "Jason"; computeHmac(hmac, buffer, strlen(buffer), key, strlen(key) ); char hmacHex[41]; toHex(hmac, 20, hmacHex ); hmacHex[40] =0; strcat(buffer,hmacHex); int l = strlen(buffer); assert( l+1 < STUN_MAX_STRING ); assert( l%4 == 0 ); username->sizeValue = l; memcpy(username->value,buffer,l); username->value[l]=0; //if (verbose) clog << "computed username=" << username.value << endl; }
unsigned int stunEncodeMessage | ( | const StunMessage & | message, | |
char * | buf, | |||
unsigned int | bufLen, | |||
const StunAtrString & | password, | |||
bool | verbose | |||
) |
Definition at line 544 of file stun.cc.
Referenced by stunSendTest(), and stunServerProcess().
{ assert(bufLen >= sizeof(StunMsgHdr)); char* ptr = buf; ptr = encode16(ptr, msg.msgHdr.msgType); char* lengthp = ptr; ptr = encode16(ptr, 0); ptr = encode(ptr, reinterpret_cast<const char*>(msg.msgHdr.id.octet), sizeof(msg.msgHdr.id)); if (verbose) clog << "Encoding stun message: " << endl; if (msg.hasMappedAddress) { if (verbose) clog << "Encoding MappedAddress: " << msg.mappedAddress.ipv4 << endl; ptr = encodeAtrAddress4 (ptr, MappedAddress, msg.mappedAddress); } if (msg.hasResponseAddress) { if (verbose) clog << "Encoding ResponseAddress: " << msg.responseAddress.ipv4 << endl; ptr = encodeAtrAddress4(ptr, ResponseAddress, msg.responseAddress); } if (msg.hasChangeRequest) { if (verbose) clog << "Encoding ChangeRequest: " << msg.changeRequest.value << endl; ptr = encodeAtrChangeRequest(ptr, msg.changeRequest); } if (msg.hasSourceAddress) { if (verbose) clog << "Encoding SourceAddress: " << msg.sourceAddress.ipv4 << endl; ptr = encodeAtrAddress4(ptr, SourceAddress, msg.sourceAddress); } if (msg.hasChangedAddress) { if (verbose) clog << "Encoding ChangedAddress: " << msg.changedAddress.ipv4 << endl; ptr = encodeAtrAddress4(ptr, ChangedAddress, msg.changedAddress); } if (msg.hasUsername) { if (verbose) clog << "Encoding Username: " << msg.username.value << endl; ptr = encodeAtrString(ptr, Username, msg.username); } if (msg.hasPassword) { if (verbose) clog << "Encoding Password: " << msg.password.value << endl; ptr = encodeAtrString(ptr, Password, msg.password); } if (msg.hasErrorCode) { if (verbose) clog << "Encoding ErrorCode: class=" << int(msg.errorCode.errorClass) << " number=" << int(msg.errorCode.number) << " reason=" << msg.errorCode.reason << endl; ptr = encodeAtrError(ptr, msg.errorCode); } if (msg.hasUnknownAttributes) { if (verbose) clog << "Encoding UnknownAttribute: ???" << endl; ptr = encodeAtrUnknown(ptr, msg.unknownAttributes); } if (msg.hasReflectedFrom) { if (verbose) clog << "Encoding ReflectedFrom: " << msg.reflectedFrom.ipv4 << endl; ptr = encodeAtrAddress4(ptr, ReflectedFrom, msg.reflectedFrom); } if (msg.hasXorMappedAddress) { if (verbose) clog << "Encoding XorMappedAddress: " << msg.xorMappedAddress.ipv4 << endl; ptr = encodeAtrAddress4 (ptr, XorMappedAddress, msg.xorMappedAddress); } if (msg.xorOnly) { if (verbose) clog << "Encoding xorOnly: " << endl; ptr = encodeXorOnly( ptr ); } if (msg.hasServerName) { if (verbose) clog << "Encoding ServerName: " << msg.serverName.value << endl; ptr = encodeAtrString(ptr, ServerName, msg.serverName); } if (msg.hasSecondaryAddress) { if (verbose) clog << "Encoding SecondaryAddress: " << msg.secondaryAddress.ipv4 << endl; ptr = encodeAtrAddress4 (ptr, SecondaryAddress, msg.secondaryAddress); } if (password.sizeValue > 0) { if (verbose) clog << "HMAC with password: " << password.value << endl; StunAtrIntegrity integrity; computeHmac(integrity.hash, buf, int(ptr-buf) , password.value, password.sizeValue); ptr = encodeAtrIntegrity(ptr, integrity); } if (verbose) clog << endl; encode16(lengthp, UInt16(ptr - buf - sizeof(StunMsgHdr))); return int(ptr - buf); }
int stunFindLocalInterfaces | ( | UInt32 * | addresses, | |
int | maxSize | |||
) |
returns number of address found - take array or addres
Definition at line 1630 of file stun.cc.
{ #if defined(WIN32) || defined(__sparc__) return 0; #else struct ifconf ifc; int s = socket( AF_INET, SOCK_DGRAM, 0 ); int len = 100 * sizeof(struct ifreq); char buf[ len ]; ifc.ifc_len = len; ifc.ifc_buf = buf; int e = ioctl(s,SIOCGIFCONF,&ifc); char *ptr = buf; int tl = ifc.ifc_len; int count=0; while ( (tl > 0) && ( count < maxRet) ) { struct ifreq* ifr = (struct ifreq *)ptr; int si = sizeof(ifr->ifr_name) + sizeof(struct sockaddr); tl -= si; ptr += si; //char* name = ifr->ifr_ifrn.ifrn_name; //cerr << "name = " << name << endl; struct ifreq ifr2; ifr2 = *ifr; e = ioctl(s,SIOCGIFADDR,&ifr2); if ( e == -1 ) { break; } //cerr << "ioctl addr e = " << e << endl; struct sockaddr a = ifr2.ifr_addr; struct sockaddr_in* addr = (struct sockaddr_in*) &a; UInt32 ai = ntohl( addr->sin_addr.s_addr ); if (int((ai>>24)&0xFF) != 127) { addresses[count++] = ai; } #if 0 cerr << "Detected interface " << int((ai>>24)&0xFF) << "." << int((ai>>16)&0xFF) << "." << int((ai>> 8)&0xFF) << "." << int((ai )&0xFF) << endl; #endif } stunclosesocket(s); return count; #endif }
UInt64 stunGetSystemTimeSecs | ( | ) |
Definition at line 817 of file stun.cc.
Referenced by stunCreateUserName().
{ UInt64 time=0; #if defined(WIN32) SYSTEMTIME t; // CJ TODO - this probably has bug on wrap around every 24 hours GetSystemTime( &t ); time = (t.wHour*60+t.wMinute)*60+t.wSecond; #else struct timeval now; gettimeofday( &now , NULL ); //assert( now ); time = now.tv_sec; #endif return time; }
void stunGetUserNameAndPassword | ( | const StunAddress4 & | dest, | |
StunAtrString * | username, | |||
StunAtrString * | password | |||
) |
Definition at line 1801 of file stun.cc.
Referenced by stunNatType(), stunOpenSocket(), stunOpenSocketPair(), and stunTest().
{ // !cj! This is totally bogus - need to make TLS connection to dest and get a // username and password to use stunCreateUserName(dest, username); stunCreatePassword(*username, password); }
bool stunInitServer | ( | StunServerInfo & | info, | |
const StunAddress4 & | myAddr, | |||
const StunAddress4 & | altAddr, | |||
int | startMediaPort, | |||
bool | verbose | |||
) |
return true if all is OK Create a media relay and do the STERN thing if startMediaPort is non-zero
Definition at line 1249 of file stun.cc.
{ assert( myAddr.port != 0 ); assert( altAddr.port!= 0 ); assert( myAddr.addr != 0 ); //assert( altAddr.addr != 0 ); info.myAddr = myAddr; info.altAddr = altAddr; info.myFd = STUN_INVALID_SOCKET; info.altPortFd = STUN_INVALID_SOCKET; info.altIpFd = STUN_INVALID_SOCKET; info.altIpPortFd = STUN_INVALID_SOCKET; memset(info.relays, 0, sizeof(info.relays)); if (startMediaPort > 0) { info.relay = true; for (int i=0; i<MAX_MEDIA_RELAYS; ++i) { StunMediaRelay* relay = &info.relays[i]; relay->relayPort = startMediaPort+i; relay->fd = 0; relay->expireTime = 0; } } else { info.relay = false; } if ((info.myFd = openPort(myAddr.port, myAddr.addr,verbose)) == STUN_INVALID_SOCKET) { clog << "Can't open " << myAddr << endl; stunStopServer(info); return false; } //if (verbose) clog << "Opened " << myAddr.addr << ":" << myAddr.port << " --> " << info.myFd << endl; if ((info.altPortFd = openPort(altAddr.port,myAddr.addr,verbose)) == STUN_INVALID_SOCKET) { clog << "Can't open " << myAddr << endl; stunStopServer(info); return false; } //if (verbose) clog << "Opened " << myAddr.addr << ":" << altAddr.port << " --> " << info.altPortFd << endl; info.altIpFd = STUN_INVALID_SOCKET; if ( altAddr.addr != 0 ) { if ((info.altIpFd = openPort( myAddr.port, altAddr.addr,verbose)) == STUN_INVALID_SOCKET) { clog << "Can't open " << altAddr << endl; stunStopServer(info); return false; } //if (verbose) clog << "Opened " << altAddr.addr << ":" << myAddr.port << " --> " << info.altIpFd << endl;; } info.altIpPortFd = STUN_INVALID_SOCKET; if ( altAddr.addr != 0 ) { if ((info.altIpPortFd = openPort(altAddr.port, altAddr.addr,verbose)) == STUN_INVALID_SOCKET) { clog << "Can't open " << altAddr << endl; stunStopServer(info); return false; } //if (verbose) clog << "Opened " << altAddr.addr << ":" << altAddr.port << " --> " << info.altIpPortFd << endl;; } return true; }
NatType stunNatType | ( | StunAddress4 & | dest, | |
bool | verbose, | |||
bool * | preservePort = 0 , |
|||
bool * | hairpin = 0 , |
|||
int | port = 0 , |
|||
StunAddress4 * | sAddr = 0 | |||
) |
Definition at line 1876 of file stun.cc.
Referenced by SingleHostUnderlayConfigurator::initializeUnderlay().
{ assert( dest.addr != 0 ); assert( dest.port != 0 ); if ( hairpin ) { *hairpin = false; } if ( port == 0 ) { port = stunRandomPort(); } UInt32 interfaceIp=0; if (sAddr) { interfaceIp = sAddr->addr; } Socket myFd1 = openPort(port,interfaceIp,verbose); Socket myFd2 = openPort(port+1,interfaceIp,verbose); if ( ( myFd1 == STUN_INVALID_SOCKET) || ( myFd2 == STUN_INVALID_SOCKET) ) { cerr << "Some problem opening port/interface to send on" << endl; return StunTypeFailure; } assert( myFd1 != STUN_INVALID_SOCKET ); assert( myFd2 != STUN_INVALID_SOCKET ); bool respTestI=false; bool isNat=true; StunAddress4 testIchangedAddr; StunAddress4 testImappedAddr; bool respTestI2=false; bool mappedIpSame = true; StunAddress4 testI2mappedAddr; StunAddress4 testI2dest=dest; bool respTestII=false; bool respTestIII=false; bool respTestHairpin=false; bool respTestPreservePort=false; memset(&testImappedAddr,0,sizeof(testImappedAddr)); StunAtrString username; StunAtrString password; username.sizeValue = 0; password.sizeValue = 0; #ifdef USE_TLS stunGetUserNameAndPassword( dest, username, password ); #endif int count=0; while ( count < 7 ) { struct timeval tv; fd_set fdSet; #ifdef WIN32 unsigned int fdSetSize; #else int fdSetSize; #endif FD_ZERO(&fdSet); fdSetSize=0; FD_SET(myFd1,&fdSet); fdSetSize = (myFd1+1>fdSetSize) ? myFd1+1 : fdSetSize; FD_SET(myFd2,&fdSet); fdSetSize = (myFd2+1>fdSetSize) ? myFd2+1 : fdSetSize; tv.tv_sec=0; tv.tv_usec=150*1000; // 150 ms if ( count == 0 ) tv.tv_usec=0; int err = select(fdSetSize, &fdSet, NULL, NULL, &tv); int e = getErrno(); if ( err == STUN_SOCKET_ERROR ) { // error occured cerr << "Error " << e << " " << strerror(e) << " in select" << endl; return StunTypeFailure; } else if ( err == 0 ) { // timeout occured count++; if ( !respTestI ) { stunSendTest( myFd1, dest, username, password, 1 ,verbose ); } if ( (!respTestI2) && respTestI ) { // check the address to send to if valid if ( ( testI2dest.addr != 0 ) && ( testI2dest.port != 0 ) ) { stunSendTest( myFd1, testI2dest, username, password, 10 ,verbose); } } if ( !respTestII ) { stunSendTest( myFd2, dest, username, password, 2 ,verbose ); } if ( !respTestIII ) { stunSendTest( myFd2, dest, username, password, 3 ,verbose ); } if ( respTestI && (!respTestHairpin) ) { if ( ( testImappedAddr.addr != 0 ) && ( testImappedAddr.port != 0 ) ) { stunSendTest( myFd1, testImappedAddr, username, password, 11 ,verbose ); } } } else { //if (verbose) clog << "-----------------------------------------" << endl; assert( err>0 ); // data is avialbe on some fd for ( int i=0; i<2; i++) { Socket myFd; if ( i==0 ) { myFd=myFd1; } else { myFd=myFd2; } if ( myFd!=STUN_INVALID_SOCKET ) { if ( FD_ISSET(myFd,&fdSet) ) { char msg[STUN_MAX_MESSAGE_SIZE]; int msgLen = sizeof(msg); StunAddress4 from; getMessage( myFd, msg, &msgLen, &from.addr, &from.port,verbose ); StunMessage resp; memset(&resp, 0, sizeof(StunMessage)); stunParseMessage( msg,msgLen, resp,verbose ); if ( verbose ) { clog << "Received message of type " << resp.msgHdr.msgType << " id=" << (int)(resp.msgHdr.id.octet[0]) << endl; } switch( resp.msgHdr.id.octet[0] ) { case 1: { if ( !respTestI ) { testIchangedAddr.addr = resp.changedAddress.ipv4.addr; testIchangedAddr.port = resp.changedAddress.ipv4.port; testImappedAddr.addr = resp.mappedAddress.ipv4.addr; testImappedAddr.port = resp.mappedAddress.ipv4.port; respTestPreservePort = ( testImappedAddr.port == port ); if ( preservePort ) { *preservePort = respTestPreservePort; } testI2dest.addr = resp.changedAddress.ipv4.addr; if (sAddr) { sAddr->port = testImappedAddr.port; sAddr->addr = testImappedAddr.addr; } count = 0; } respTestI=true; } break; case 2: { respTestII=true; } break; case 3: { respTestIII=true; } break; case 10: { if ( !respTestI2 ) { testI2mappedAddr.addr = resp.mappedAddress.ipv4.addr; testI2mappedAddr.port = resp.mappedAddress.ipv4.port; mappedIpSame = false; if ( (testI2mappedAddr.addr == testImappedAddr.addr ) && (testI2mappedAddr.port == testImappedAddr.port )) { mappedIpSame = true; } } respTestI2=true; } break; case 11: { if ( hairpin ) { *hairpin = true; } respTestHairpin = true; } break; } } } } } } // see if we can bind to this address //cerr << "try binding to " << testImappedAddr << endl; Socket s = openPort( 0/*use ephemeral*/, testImappedAddr.addr, false ); if ( s != STUN_INVALID_SOCKET ) { stunclosesocket(s); isNat = false; //cerr << "binding worked" << endl; } else { isNat = true; //cerr << "binding failed" << endl; } if (verbose) { clog << "test I = " << respTestI << endl; clog << "test II = " << respTestII << endl; clog << "test III = " << respTestIII << endl; clog << "test I(2) = " << respTestI2 << endl; clog << "is nat = " << isNat <<endl; clog << "mapped IP same = " << mappedIpSame << endl; clog << "hairpin = " << respTestHairpin << endl; clog << "preserver port = " << respTestPreservePort << endl; } #if 0 // implement logic flow chart from draft RFC if ( respTestI ) { if ( isNat ) { if (respTestII) { return StunTypeConeNat; } else { if ( mappedIpSame ) { if ( respTestIII ) { return StunTypeRestrictedNat; } else { return StunTypePortRestrictedNat; } } else { return StunTypeSymNat; } } } else { if (respTestII) { return StunTypeOpen; } else { return StunTypeSymFirewall; } } } else { return StunTypeBlocked; } #else if ( respTestI ) // not blocked { if ( isNat ) { if ( mappedIpSame ) { if (respTestII) { return StunTypeIndependentFilter; } else { if ( respTestIII ) { return StunTypeDependentFilter; } else { return StunTypePortDependedFilter; } } } else // mappedIp is not same { return StunTypeDependentMapping; } } else // isNat is false { if (respTestII) { return StunTypeOpen; } else { return StunTypeFirewall; } } } else { return StunTypeBlocked; } #endif return StunTypeUnknown; }
int stunOpenSocket | ( | StunAddress4 & | dest, | |
StunAddress4 * | mappedAddr, | |||
int | port = 0 , |
|||
StunAddress4 * | srcAddr = 0 , |
|||
bool | verbose = false | |||
) |
Definition at line 2247 of file stun.cc.
{ assert( dest.addr != 0 ); assert( dest.port != 0 ); assert( mapAddr ); if ( port == 0 ) { port = stunRandomPort(); } unsigned int interfaceIp = 0; if ( srcAddr ) { interfaceIp = srcAddr->addr; } Socket myFd = openPort(port,interfaceIp,verbose); if (myFd == STUN_INVALID_SOCKET) { return myFd; } char msg[STUN_MAX_MESSAGE_SIZE]; int msgLen = sizeof(msg); StunAtrString username; StunAtrString password; username.sizeValue = 0; password.sizeValue = 0; #ifdef USE_TLS stunGetUserNameAndPassword( dest, username, password ); #endif stunSendTest(myFd, dest, username, password, 1, 0/*false*/ ); StunAddress4 from; getMessage( myFd, msg, &msgLen, &from.addr, &from.port,verbose ); StunMessage resp; memset(&resp, 0, sizeof(StunMessage)); bool ok = stunParseMessage( msg, msgLen, resp,verbose ); if (!ok) { return -1; } StunAddress4 mappedAddr = resp.mappedAddress.ipv4; StunAddress4 changedAddr = resp.changedAddress.ipv4; //clog << "--- stunOpenSocket --- " << endl; //clog << "\treq id=" << req.id << endl; //clog << "\tresp id=" << id << endl; //clog << "\tmappedAddr=" << mappedAddr << endl; *mapAddr = mappedAddr; return myFd; }
bool stunOpenSocketPair | ( | StunAddress4 & | dest, | |
StunAddress4 * | mappedAddr, | |||
int * | fd1, | |||
int * | fd2, | |||
int | srcPort = 0 , |
|||
StunAddress4 * | srcAddr = 0 , |
|||
bool | verbose = false | |||
) |
Definition at line 2314 of file stun.cc.
{ assert( dest.addr!= 0 ); assert( dest.port != 0 ); assert( mapAddr ); const int NUM=3; if ( port == 0 ) { port = stunRandomPort(); } *fd1=-1; *fd2=-1; char msg[STUN_MAX_MESSAGE_SIZE]; int msgLen =sizeof(msg); StunAddress4 from; int fd[NUM]; int i; unsigned int interfaceIp = 0; if ( srcAddr ) { interfaceIp = srcAddr->addr; } for( i=0; i<NUM; i++) { fd[i] = openPort( (port == 0) ? 0 : (port + i), interfaceIp, verbose); if (fd[i] < 0) { while (i > 0) { stunclosesocket(fd[--i]); } return false; } } StunAtrString username; StunAtrString password; username.sizeValue = 0; password.sizeValue = 0; #ifdef USE_TLS stunGetUserNameAndPassword( dest, username, password ); #endif for( i=0; i<NUM; i++) { stunSendTest(fd[i], dest, username, password, 1/*testNum*/, verbose ); } StunAddress4 mappedAddr[NUM]; for( i=0; i<NUM; i++) { msgLen = sizeof(msg)/sizeof(*msg); getMessage( fd[i], msg, &msgLen, &from.addr, &from.port ,verbose); StunMessage resp; memset(&resp, 0, sizeof(StunMessage)); bool ok = stunParseMessage( msg, msgLen, resp, verbose ); if (!ok) { return false; } mappedAddr[i] = resp.mappedAddress.ipv4; StunAddress4 changedAddr = resp.changedAddress.ipv4; } if (verbose) { clog << "--- stunOpenSocketPair --- " << endl; for( i=0; i<NUM; i++) { clog << "\t mappedAddr=" << mappedAddr[i] << endl; } } if ( mappedAddr[0].port %2 == 0 ) { if ( mappedAddr[0].port+1 == mappedAddr[1].port ) { *mapAddr = mappedAddr[0]; *fd1 = fd[0]; *fd2 = fd[1]; stunclosesocket( fd[2] ); return true; } } else { if (( mappedAddr[1].port %2 == 0 ) && ( mappedAddr[1].port+1 == mappedAddr[2].port )) { *mapAddr = mappedAddr[1]; *fd1 = fd[1]; *fd2 = fd[2]; stunclosesocket( fd[0] ); return true; } } // something failed, close all and return error for( i=0; i<NUM; i++) { stunclosesocket( fd[i] ); } return false; }
Definition at line 863 of file stun.cc.
Referenced by stunParseServerName().
{ in_addr sin_addr; char host[512]; strncpy(host,peerName,512); host[512-1]='\0'; char* port = NULL; int portNum = defaultPort; // pull out the port part if present. char* sep = strchr(host,':'); if ( sep == NULL ) { portNum = defaultPort; } else { *sep = '\0'; port = sep + 1; // set port part char* endPtr=NULL; portNum = strtol(port,&endPtr,10); if ( endPtr != NULL ) { if ( *endPtr != '\0' ) { portNum = defaultPort; } } } if ( portNum < 1024 ) return false; if ( portNum >= 0xFFFF ) return false; // figure out the host part struct hostent* h; #ifdef WIN32 assert( strlen(host) >= 1 ); if ( isdigit( host[0] ) ) { // assume it is a ip address unsigned long a = inet_addr(host); //cerr << "a=0x" << hex << a << dec << endl; ip = ntohl( a ); } else { // assume it is a host name h = gethostbyname( host ); if ( h == NULL ) { int err = getErrno(); std::cerr << "error was " << err << std::endl; assert( err != WSANOTINITIALISED ); ip = ntohl( 0x7F000001L ); return false; } else { sin_addr = *(struct in_addr*)h->h_addr; ip = ntohl( sin_addr.s_addr ); } } #else h = gethostbyname( host ); if ( h == NULL ) { int err = getErrno(); std::cerr << "error was " << err << std::endl; ip = ntohl( 0x7F000001L ); return false; } else { sin_addr = *(struct in_addr*)h->h_addr; ip = ntohl( sin_addr.s_addr ); } #endif portVal = portNum; return true; }
bool stunParseMessage | ( | char * | buf, | |
unsigned int | bufLen, | |||
StunMessage & | message, | |||
bool | verbose | |||
) |
Definition at line 183 of file stun.cc.
Referenced by stunNatType(), stunOpenSocket(), stunOpenSocketPair(), stunServerProcessMsg(), and stunTest().
{ if (verbose) clog << "Received stun message: " << bufLen << " bytes" << endl; memset(&msg, 0, sizeof(msg)); if (sizeof(StunMsgHdr) > bufLen) { clog << "Bad message" << endl; return false; } memcpy(&msg.msgHdr, buf, sizeof(StunMsgHdr)); msg.msgHdr.msgType = ntohs(msg.msgHdr.msgType); msg.msgHdr.msgLength = ntohs(msg.msgHdr.msgLength); if (msg.msgHdr.msgLength + sizeof(StunMsgHdr) != bufLen) { clog << "Message header length doesn't match message size: " << msg.msgHdr.msgLength << " - " << bufLen << endl; return false; } char* body = buf + sizeof(StunMsgHdr); unsigned int size = msg.msgHdr.msgLength; //clog << "bytes after header = " << size << endl; while ( size > 0 ) { // !jf! should check that there are enough bytes left in the buffer StunAtrHdr* attr = reinterpret_cast<StunAtrHdr*>(body); unsigned int attrLen = ntohs(attr->length); int atrType = ntohs(attr->type); //if (verbose) clog << "Found attribute type=" << AttrNames[atrType] << " length=" << attrLen << endl; if ( attrLen+4 > size ) { clog << "claims attribute is larger than size of message " <<"(attribute type="<<atrType<<")"<< endl; return false; } body += 4; // skip the length and type in attribute header size -= 4; switch ( atrType ) { case MappedAddress: msg.hasMappedAddress = true; if ( stunParseAtrAddress( body, attrLen, msg.mappedAddress )== false ) { clog << "problem parsing MappedAddress" << endl; return false; } else { if (verbose) clog << "MappedAddress = " << msg.mappedAddress.ipv4 << endl; } break; case ResponseAddress: msg.hasResponseAddress = true; if ( stunParseAtrAddress( body, attrLen, msg.responseAddress )== false ) { clog << "problem parsing ResponseAddress" << endl; return false; } else { if (verbose) clog << "ResponseAddress = " << msg.responseAddress.ipv4 << endl; } break; case ChangeRequest: msg.hasChangeRequest = true; if (stunParseAtrChangeRequest( body, attrLen, msg.changeRequest) == false) { clog << "problem parsing ChangeRequest" << endl; return false; } else { if (verbose) clog << "ChangeRequest = " << msg.changeRequest.value << endl; } break; case SourceAddress: msg.hasSourceAddress = true; if ( stunParseAtrAddress( body, attrLen, msg.sourceAddress )== false ) { clog << "problem parsing SourceAddress" << endl; return false; } else { if (verbose) clog << "SourceAddress = " << msg.sourceAddress.ipv4 << endl; } break; case ChangedAddress: msg.hasChangedAddress = true; if ( stunParseAtrAddress( body, attrLen, msg.changedAddress )== false ) { clog << "problem parsing ChangedAddress" << endl; return false; } else { if (verbose) clog << "ChangedAddress = " << msg.changedAddress.ipv4 << endl; } break; case Username: msg.hasUsername = true; if (stunParseAtrString( body, attrLen, msg.username) == false) { clog << "problem parsing Username" << endl; return false; } else { if (verbose) clog << "Username = " << msg.username.value << endl; } break; case Password: msg.hasPassword = true; if (stunParseAtrString( body, attrLen, msg.password) == false) { clog << "problem parsing Password" << endl; return false; } else { if (verbose) clog << "Password = " << msg.password.value << endl; } break; case MessageIntegrity: msg.hasMessageIntegrity = true; if (stunParseAtrIntegrity( body, attrLen, msg.messageIntegrity) == false) { clog << "problem parsing MessageIntegrity" << endl; return false; } else { //if (verbose) clog << "MessageIntegrity = " << msg.messageIntegrity.hash << endl; } // read the current HMAC // look up the password given the user of given the transaction id // compute the HMAC on the buffer // decide if they match or not break; case ErrorCode: msg.hasErrorCode = true; if (stunParseAtrError(body, attrLen, msg.errorCode) == false) { clog << "problem parsing ErrorCode" << endl; return false; } else { if (verbose) clog << "ErrorCode = " << int(msg.errorCode.errorClass) << " " << int(msg.errorCode.number) << " " << msg.errorCode.reason << endl; } break; case UnknownAttribute: msg.hasUnknownAttributes = true; if (stunParseAtrUnknown(body, attrLen, msg.unknownAttributes) == false) { clog << "problem parsing UnknownAttribute" << endl; return false; } break; case ReflectedFrom: msg.hasReflectedFrom = true; if ( stunParseAtrAddress( body, attrLen, msg.reflectedFrom ) == false ) { clog << "problem parsing ReflectedFrom" << endl; return false; } break; case XorMappedAddress: msg.hasXorMappedAddress = true; if ( stunParseAtrAddress( body, attrLen, msg.xorMappedAddress ) == false ) { clog << "problem parsing XorMappedAddress" << endl; return false; } else { if (verbose) clog << "XorMappedAddress = " << msg.mappedAddress.ipv4 << endl; } break; case XorOnly: msg.xorOnly = true; if (verbose) { clog << "xorOnly = true" << endl; } break; case ServerName: msg.hasServerName = true; if (stunParseAtrString( body, attrLen, msg.serverName) == false) { clog << "problem parsing ServerName" << endl; return false; } else { if (verbose) clog << "ServerName = " << msg.serverName.value << endl; } break; case SecondaryAddress: msg.hasSecondaryAddress = true; if ( stunParseAtrAddress( body, attrLen, msg.secondaryAddress ) == false ) { clog << "problem parsing secondaryAddress" << endl; return false; } else { if (verbose) clog << "SecondaryAddress = " << msg.secondaryAddress.ipv4 << endl; } break; default: if (verbose) clog << "Unknown attribute: " << atrType << endl; if ( atrType <= 0x7FFF ) { return false; } } body += attrLen; size -= attrLen; } return true; }
bool stunParseServerName | ( | char * | serverName, | |
StunAddress4 & | stunServerAddr | |||
) |
find the IP address of a the specified stun server - return false is fails parse
Definition at line 964 of file stun.cc.
Referenced by SingleHostUnderlayConfigurator::initializeUnderlay().
{ assert(name); // TODO - put in DNS SRV stuff. bool ret = stunParseHostName( name, addr.addr, addr.port, 3478); if ( ret != true ) { addr.port=0xFFFF; } return ret; }
int stunRand | ( | ) |
Definition at line 651 of file stun.cc.
Referenced by stunBuildReqSimple(), stunCreateUserName(), and stunRandomPort().
{ // return 32 bits of random stuff assert( sizeof(int) == 4 ); static bool init=false; if ( !init ) { init = true; UInt64 tick; #if defined(MSVC_WIN32) volatile unsigned int lowtick=0,hightick=0; __asm { rdtsc mov lowtick, eax mov hightick, edx } tick = hightick; tick <<= 32; tick |= lowtick; #elif (defined(WIN32) || defined(__GNUC__)) && ( defined(__i686__) || defined(__i386__) || defined(__x86_64__) ) asm("rdtsc" : "=A" (tick)); #elif defined (__SUNPRO_CC) || defined( __sparc__ ) tick = gethrtime(); #elif defined(__MACH__) int fd=open("/dev/random",O_RDONLY); read(fd,&tick,sizeof(tick)); stunclosesocket(fd); #else # error Need some way to seed the random number generator #endif int seed = int(tick); #ifdef WIN32 srand(seed); #else srandom(seed); #endif } #ifdef WIN32 assert( RAND_MAX == 0x7fff ); int r1 = rand(); int r2 = rand(); int ret = (r1<<16) + r2; return ret; #else return random(); #endif }
int stunRandomPort | ( | ) |
return a random number to use as a port
Definition at line 708 of file stun.cc.
Referenced by stunNatType(), stunOpenSocket(), stunOpenSocketPair(), and stunTest().
{ int min=0x4000; int max=0x7FFF; int ret = stunRand(); ret = ret|min; ret = ret&max; return ret; }
bool stunServerProcess | ( | StunServerInfo & | info, | |
bool | verbose | |||
) |
return true if all is OK
Definition at line 1351 of file stun.cc.
{ char msg[STUN_MAX_MESSAGE_SIZE]; int msgLen = sizeof(msg); bool ok = false; bool recvAltIp =false; bool recvAltPort = false; fd_set fdSet; Socket maxFd=0; FD_ZERO(&fdSet); FD_SET(info.myFd,&fdSet); if ( info.myFd >= maxFd ) maxFd=info.myFd+1; FD_SET(info.altPortFd,&fdSet); if ( info.altPortFd >= maxFd ) maxFd=info.altPortFd+1; if ( info.altIpFd != STUN_INVALID_SOCKET ) { FD_SET(info.altIpFd,&fdSet); if (info.altIpFd>=maxFd) maxFd=info.altIpFd+1; } if ( info.altIpPortFd != STUN_INVALID_SOCKET ) { FD_SET(info.altIpPortFd,&fdSet); if (info.altIpPortFd>=maxFd) maxFd=info.altIpPortFd+1; } if (info.relay) { for (int i=0; i<MAX_MEDIA_RELAYS; ++i) { StunMediaRelay* relay = &info.relays[i]; if (relay->fd) { FD_SET(relay->fd, &fdSet); if (relay->fd >= maxFd) { maxFd=relay->fd+1; } } } } if ( info.altIpFd != STUN_INVALID_SOCKET ) { FD_SET(info.altIpFd,&fdSet); if (info.altIpFd>=maxFd) maxFd=info.altIpFd+1; } if ( info.altIpPortFd != STUN_INVALID_SOCKET ) { FD_SET(info.altIpPortFd,&fdSet); if (info.altIpPortFd>=maxFd) maxFd=info.altIpPortFd+1; } struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 1000; int e = select( maxFd, &fdSet, NULL,NULL, &tv ); if (e < 0) { int err = getErrno(); clog << "Error on select: " << strerror(err) << endl; } else if (e >= 0) { StunAddress4 from; // do the media relaying if (info.relay) { time_t now = time(0); for (int i=0; i<MAX_MEDIA_RELAYS; ++i) { StunMediaRelay* relay = &info.relays[i]; if (relay->fd) { if (FD_ISSET(relay->fd, &fdSet)) { char msg[MAX_RTP_MSG_SIZE]; int msgLen = sizeof(msg); StunAddress4 rtpFrom; ok = getMessage( relay->fd, msg, &msgLen, &rtpFrom.addr, &rtpFrom.port ,verbose); if (ok) { sendMessage(info.myFd, msg, msgLen, relay->destination.addr, relay->destination.port, verbose); relay->expireTime = now + MEDIA_RELAY_TIMEOUT; if ( verbose ) clog << "Relay packet on " << relay->fd << " from " << rtpFrom << " -> " << relay->destination << endl; } } else if (now > relay->expireTime) { stunclosesocket(relay->fd); relay->fd = 0; } } } } if (FD_ISSET(info.myFd,&fdSet)) { if (verbose) clog << "received on A1:P1" << endl; recvAltIp = false; recvAltPort = false; ok = getMessage( info.myFd, msg, &msgLen, &from.addr, &from.port,verbose ); } else if (FD_ISSET(info.altPortFd, &fdSet)) { if (verbose) clog << "received on A1:P2" << endl; recvAltIp = false; recvAltPort = true; ok = getMessage( info.altPortFd, msg, &msgLen, &from.addr, &from.port,verbose ); } else if ( (info.altIpFd!=STUN_INVALID_SOCKET) && FD_ISSET(info.altIpFd,&fdSet)) { if (verbose) clog << "received on A2:P1" << endl; recvAltIp = true; recvAltPort = false; ok = getMessage( info.altIpFd, msg, &msgLen, &from.addr, &from.port ,verbose); } else if ( (info.altIpPortFd!=STUN_INVALID_SOCKET) && FD_ISSET(info.altIpPortFd, &fdSet)) { if (verbose) clog << "received on A2:P2" << endl; recvAltIp = true; recvAltPort = true; ok = getMessage( info.altIpPortFd, msg, &msgLen, &from.addr, &from.port,verbose ); } else { return true; } int relayPort = 0; if (info.relay) { for (int i=0; i<MAX_MEDIA_RELAYS; ++i) { StunMediaRelay* relay = &info.relays[i]; if (relay->destination.addr == from.addr && relay->destination.port == from.port) { relayPort = relay->relayPort; relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT; break; } } if (relayPort == 0) { for (int i=0; i<MAX_MEDIA_RELAYS; ++i) { StunMediaRelay* relay = &info.relays[i]; if (relay->fd == 0) { if ( verbose ) clog << "Open relay port " << relay->relayPort << endl; relay->fd = openPort(relay->relayPort, info.myAddr.addr, verbose); relay->destination.addr = from.addr; relay->destination.port = from.port; relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT; relayPort = relay->relayPort; break; } } } } if ( !ok ) { if ( verbose ) clog << "Get message did not return a valid message" <<endl; return true; } if ( verbose ) clog << "Got a request (len=" << msgLen << ") from " << from << endl; if ( msgLen <= 0 ) { return true; } bool changePort = false; bool changeIp = false; StunMessage resp; StunAddress4 dest; StunAtrString hmacPassword; hmacPassword.sizeValue = 0; StunAddress4 secondary; secondary.port = 0; secondary.addr = 0; if (info.relay && relayPort) { secondary = from; from.addr = info.myAddr.addr; from.port = relayPort; } ok = stunServerProcessMsg( msg, msgLen, from, secondary, recvAltIp ? info.altAddr : info.myAddr, recvAltIp ? info.myAddr : info.altAddr, &resp, &dest, &hmacPassword, &changePort, &changeIp, verbose ); if ( !ok ) { if ( verbose ) clog << "Failed to parse message" << endl; return true; } char buf[STUN_MAX_MESSAGE_SIZE]; int len = sizeof(buf); len = stunEncodeMessage( resp, buf, len, hmacPassword,verbose ); if ( dest.addr == 0 ) ok=false; if ( dest.port == 0 ) ok=false; if ( ok ) { assert( dest.addr != 0 ); assert( dest.port != 0 ); Socket sendFd; bool sendAltIp = recvAltIp; // send on the received IP address bool sendAltPort = recvAltPort; // send on the received port if ( changeIp ) sendAltIp = !sendAltIp; // if need to change IP, then flip logic if ( changePort ) sendAltPort = !sendAltPort; // if need to change port, then flip logic if ( !sendAltPort ) { if ( !sendAltIp ) { sendFd = info.myFd; } else { sendFd = info.altIpFd; } } else { if ( !sendAltIp ) { sendFd = info.altPortFd; } else { sendFd = info.altIpPortFd; } } if ( sendFd != STUN_INVALID_SOCKET ) { sendMessage( sendFd, buf, len, dest.addr, dest.port, verbose ); } } } return true; }
bool stunServerProcessMsg | ( | char * | buf, | |
unsigned int | bufLen, | |||
StunAddress4 & | from, | |||
StunAddress4 & | myAddr, | |||
StunAddress4 & | altAddr, | |||
StunMessage * | resp, | |||
StunAddress4 * | destination, | |||
StunAtrString * | hmacPassword, | |||
bool * | changePort, | |||
bool * | changeIp, | |||
bool | verbose | |||
) |
void stunStopServer | ( | StunServerInfo & | info | ) |
Definition at line 1328 of file stun.cc.
Referenced by stunInitServer().
{ if (info.myFd > 0) stunclosesocket(info.myFd); if (info.altPortFd > 0) stunclosesocket(info.altPortFd); if (info.altIpFd > 0) stunclosesocket(info.altIpFd); if (info.altIpPortFd > 0) stunclosesocket(info.altIpPortFd); if (info.relay) { for (int i=0; i<MAX_MEDIA_RELAYS; ++i) { StunMediaRelay* relay = &info.relays[i]; if (relay->fd) { stunclosesocket(relay->fd); relay->fd = 0; } } } }
void stunTest | ( | StunAddress4 & | dest, | |
int | testNum, | |||
bool | verbose, | |||
StunAddress4 * | srcAddr = 0 | |||
) |
Definition at line 1813 of file stun.cc.
{ assert( dest.addr != 0 ); assert( dest.port != 0 ); int port = stunRandomPort(); UInt32 interfaceIp=0; if (sAddr) { interfaceIp = sAddr->addr; if ( sAddr->port != 0 ) { port = sAddr->port; } } Socket myFd = openPort(port,interfaceIp,verbose); StunAtrString username; StunAtrString password; username.sizeValue = 0; password.sizeValue = 0; #ifdef USE_TLS stunGetUserNameAndPassword( dest, username, password ); #endif stunSendTest( myFd, dest, username, password, testNum, verbose ); char msg[STUN_MAX_MESSAGE_SIZE]; int msgLen = STUN_MAX_MESSAGE_SIZE; StunAddress4 from; getMessage( myFd, msg, &msgLen, &from.addr, &from.port,verbose ); StunMessage resp; memset(&resp, 0, sizeof(StunMessage)); if ( verbose ) clog << "Got a response" << endl; bool ok = stunParseMessage( msg,msgLen, resp,verbose ); if ( verbose ) { clog << "\t ok=" << ok << endl; clog << "\t id=" << resp.msgHdr.id << endl; clog << "\t mappedAddr=" << resp.mappedAddress.ipv4 << endl; clog << "\t changedAddr=" << resp.changedAddress.ipv4 << endl; clog << endl; } if (sAddr) { sAddr->port = resp.mappedAddress.ipv4.port; sAddr->addr = resp.mappedAddress.ipv4.addr; } }
const UInt16 BindErrorResponseMsg = 0x0111 |
Definition at line 55 of file stun.h.
Referenced by stunCreateErrorResponse().
const UInt16 BindRequestMsg = 0x0001 |
Definition at line 53 of file stun.h.
Referenced by stunBuildReqSimple(), and stunServerProcessMsg().
const UInt16 BindResponseMsg = 0x0101 |
Definition at line 54 of file stun.h.
Referenced by stunServerProcessMsg().
const UInt16 ChangedAddress = 0x0005 |
Definition at line 40 of file stun.h.
Referenced by stunEncodeMessage(), and stunParseMessage().
const UInt32 ChangeIpFlag = 0x04 |
Definition at line 32 of file stun.h.
Referenced by stunBuildReqSimple(), and stunServerProcessMsg().
const UInt32 ChangePortFlag = 0x02 |
Definition at line 33 of file stun.h.
Referenced by stunBuildReqSimple(), and stunServerProcessMsg().
const UInt16 ChangeRequest = 0x0003 |
Definition at line 38 of file stun.h.
Referenced by encodeAtrChangeRequest(), and stunParseMessage().
Definition at line 44 of file stun.h.
Referenced by encodeAtrError(), and stunParseMessage().
const UInt8 IPv4Family = 0x01 |
define a structure to hold a stun address
Definition at line 28 of file stun.h.
Referenced by encodeAtrAddress4(), and stunParseAtrAddress().
const UInt8 IPv6Family = 0x02 |
Definition at line 29 of file stun.h.
Referenced by stunParseAtrAddress().
const UInt16 MappedAddress = 0x0001 |
Definition at line 36 of file stun.h.
Referenced by stunEncodeMessage(), and stunParseMessage().
const UInt16 MessageIntegrity = 0x0008 |
Definition at line 43 of file stun.h.
Referenced by encodeAtrIntegrity(), and stunParseMessage().
Definition at line 42 of file stun.h.
Referenced by stunEncodeMessage(), and stunParseMessage().
const UInt16 ReflectedFrom = 0x000B |
Definition at line 46 of file stun.h.
Referenced by stunEncodeMessage(), and stunParseMessage().
const UInt16 ResponseAddress = 0x0002 |
Definition at line 37 of file stun.h.
Referenced by stunEncodeMessage(), and stunParseMessage().
const UInt16 SecondaryAddress = 0x8050 |
Definition at line 50 of file stun.h.
Referenced by stunEncodeMessage(), and stunParseMessage().
const UInt16 ServerName = 0x8022 |
Definition at line 49 of file stun.h.
Referenced by stunEncodeMessage(), and stunParseMessage().
const UInt16 SharedSecretErrorResponseMsg = 0x0112 |
const UInt16 SharedSecretRequestMsg = 0x0002 |
Definition at line 56 of file stun.h.
Referenced by stunServerProcessMsg().
const UInt16 SharedSecretResponseMsg = 0x0102 |
Definition at line 57 of file stun.h.
Referenced by stunCreateSharedSecretResponse().
const UInt16 SourceAddress = 0x0004 |
Definition at line 39 of file stun.h.
Referenced by stunEncodeMessage(), and stunParseMessage().
const UInt16 UnknownAttribute = 0x000A |
Definition at line 45 of file stun.h.
Referenced by encodeAtrUnknown(), and stunParseMessage().
Definition at line 41 of file stun.h.
Referenced by stunEncodeMessage(), and stunParseMessage().
const UInt16 XorMappedAddress = 0x8020 |
Definition at line 47 of file stun.h.
Referenced by stunEncodeMessage(), and stunParseMessage().
Definition at line 48 of file stun.h.
Referenced by encodeXorOnly(), and stunParseMessage().