📄 stun.cxx
字号:
return false; } break; //overlay on parse, ownership is buffer parsed from case TurnData: msg.hasTurnData = true; msg.turnData = new resip::Data(resip::Data::Share, body, attrLen); break; //case TurnNonce: //break; //case TurnRealm: //break; default: if (verbose) clog << "Unknown attribute: " << atrType << endl; if ( atrType <= 0x7FFF ) { return false; } } body += attrLen; size -= attrLen; } return true;}static char* encode16(char* buf, UInt16 data){ UInt16 ndata = htons(data); memcpy(buf, reinterpret_cast<void*>(&ndata), sizeof(UInt16)); return buf + sizeof(UInt16);}static char* encode32(char* buf, UInt32 data){ UInt32 ndata = htonl(data); memcpy(buf, reinterpret_cast<void*>(&ndata), sizeof(UInt32)); return buf + sizeof(UInt32);}static char* encode(char* buf, const char* data, unsigned int length){ memcpy(buf, data, length); return buf + length;}static char* encodeTurnData(char *ptr, const resip::Data* td){ ptr = encode16(ptr, TurnData); ptr = encode16(ptr, td->size()); memcpy(ptr, td->data(), td->size()); ptr += td->size(); return ptr;}static char*encodeAtrUInt32(char* ptr, UInt16 type, UInt32 value){ ptr = encode16(ptr, type); ptr = encode16(ptr, 4); ptr = encode32(ptr, value); return ptr;}static char* encodeAtrAddress4(char* ptr, UInt16 type, const StunAtrAddress4& atr){ ptr = encode16(ptr, type); ptr = encode16(ptr, 8); *ptr++ = atr.pad; *ptr++ = IPv4Family; ptr = encode16(ptr, atr.ipv4.port); ptr = encode32(ptr, atr.ipv4.addr); return ptr;}static char* encodeAtrChangeRequest(char* ptr, const StunAtrChangeRequest& atr){ ptr = encode16(ptr, ChangeRequest); ptr = encode16(ptr, 4); ptr = encode32(ptr, atr.value); return ptr;}static char* encodeMagicCookie(char* ptr, const UInt32& cookie){ ptr = encode16(ptr, TurnMagicCookie); ptr = encode16(ptr, 4); ptr = encode32(ptr, cookie); return ptr;}static char* encodeAtrError(char* ptr, const StunAtrError& atr){ ptr = encode16(ptr, ErrorCode); ptr = encode16(ptr, 4 + atr.sizeReason); ptr = encode16(ptr, atr.pad); *ptr++ = atr.errorClass; *ptr++ = atr.number; ptr = encode(ptr, atr.reason, atr.sizeReason); return ptr;}static char* encodeAtrUnknown(char* ptr, const StunAtrUnknown& atr){ ptr = encode16(ptr, UnknownAttribute); ptr = encode16(ptr, 2+2*atr.numAttributes); for (int i=0; i<atr.numAttributes; i++) { ptr = encode16(ptr, atr.attrType[i]); } return ptr;}static char* encodeXorOnly(char* ptr){ ptr = encode16(ptr, XorOnly ); return ptr;}static char* encodeAtrString(char* ptr, UInt16 type, const StunAtrString& atr){ assert(atr.sizeValue % 4 == 0); ptr = encode16(ptr, type); ptr = encode16(ptr, atr.sizeValue); ptr = encode(ptr, atr.value, atr.sizeValue); return ptr;}static char* encodeAtrIntegrity(char* ptr, const StunAtrIntegrity& atr){ ptr = encode16(ptr, MessageIntegrity); ptr = encode16(ptr, 20); ptr = encode(ptr, atr.hash, sizeof(atr.hash)); return ptr;}unsigned intstunEncodeMessage( const StunMessage& msg, char* buf, unsigned int bufLen, const StunAtrString& password, bool verbose){ assert(bufLen >= sizeof(StunMsgHdr)); char* ptr = buf; if (verbose) clog << "Encoding stun message: " << endl; 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 (msg.hasTurnMagicCookie) { if (verbose) clog << "Encoding TurnMagicCookie: " << msg.turnMagicCookie << endl; ptr = encodeMagicCookie(ptr, msg.turnMagicCookie); } if (msg.hasTurnDestinationAddress) { if (verbose) clog << "Encoding TurnDestinationAddress: " << msg.turnDestinationAddress.ipv4 << endl; ptr = encodeAtrAddress4 (ptr, TurnDestinationAddress, msg.turnDestinationAddress); } 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.hasTurnAlternateServer ) { if (verbose) clog << "Encoding AlternateServer: " << msg.turnAlternateServer.ipv4 << endl; ptr = encodeAtrAddress4 (ptr, TurnAlternateServer, msg.turnAlternateServer); } 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 (msg.hasTurnLifetime) { if (verbose) clog << "Encoding Turn Lifetime: " << msg.turnLifetime << endl; ptr = encodeAtrUInt32(ptr, TurnLifetime, msg.turnLifetime); } if (msg.hasTurnBandwidth) { if (verbose) clog << "Encoding Turn Bandwidth: " << msg.turnBandwidth << endl; ptr = encodeAtrUInt32(ptr, TurnBandwidth, msg.turnBandwidth); } if (msg.hasTurnData) { if (verbose) clog << "Encoding TurnData (not shown)" << endl; ptr = encodeTurnData (ptr, msg.turnData); } if (password.sizeValue > 0) { if (verbose) clog << "HMAC with password: " << password.value << endl; // allocate space for message integrity attribute (hash + attribute type + size) char* ptrMessageIntegrity = ptr; ptr += 20 + sizeof(MessageIntegrity) + sizeof(UInt16); encode16(lengthp, UInt16(ptr - buf - sizeof(StunMsgHdr))); StunAtrIntegrity integrity; // pad with zeros prior to calculating message integrity attribute int padding = 0; int len = ptrMessageIntegrity - buf; if (len % 64) { padding = 64 - (len % 64); memset(ptrMessageIntegrity, 0, padding); } computeHmac(integrity.hash, buf, len + padding, password.value, password.sizeValue); encodeAtrIntegrity(ptrMessageIntegrity, integrity); } if (verbose) clog << endl; encode16(lengthp, UInt16(ptr - buf - sizeof(StunMsgHdr))); return int(ptr - buf);}int stunRand(){ // return 32 bits of random stuff assert( sizeof(int) == 4 ); static bool init=false; if ( !init ) { init = true; UInt64 tick; #if defined(WIN32) #if !defined(UNDER_CE) && !defined(__GNUC__) volatile unsigned int lowtick=0,hightick=0; __asm { rdtsc mov lowtick, eax mov hightick, edx } tick = hightick; tick <<= 32; tick |= lowtick;#else tick = GetTickCount();#endif#elif defined(__GNUC__) && ( defined(__i686__) || defined(__i386__) || defined(__x86_64__) ) asm("rdtsc" : "=A" (tick));#elif defined (__SUNPRO_CC) || defined( __sparc__ ) tick = gethrtime();#elif defined(__APPLE__) || defined(__MACH__) int fd=open("/dev/random",O_RDONLY); read(fd,&tick,sizeof(tick)); closeSocket(fd);#elif defined(__linux__) int fd=open("/dev/urandom",O_RDONLY); read(fd,&tick,sizeof(tick)); closeSocket(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}/// return a random number to use as a port intstunRandomPort(){ int min=0x4000; int max=0x7FFF; int ret = stunRand(); ret = ret|min; ret = ret&max; return ret;}#ifndef USE_SSLvoidcomputeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey){ strncpy(hmac,"hmac-not-implemented",20);}#else#include <openssl/hmac.h>voidcomputeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey){ unsigned int resultSize=0; HMAC(EVP_sha1(), key, sizeKey, reinterpret_cast<const unsigned char*>(input), length, reinterpret_cast<unsigned char*>(hmac), &resultSize); assert(resultSize == 20);}#endifstatic voidtoHex(const char* buffer, int bufferSize, char* output) { static char hexmap[] = "0123456789abcdef"; const char* p = buffer; char* r = output; for (int i=0; i < bufferSize; i++) { unsigned char temp = *p++; int hi = (temp & 0xf0)>>4; int low = (temp & 0xf); *r++ = hexmap[hi]; *r++ = hexmap[low]; } *r = 0;}voidstunCreateUserName(const StunAddress4& source, StunAtrString* username){ 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;}voidstunCreatePassword(const StunAtrString& username, StunAtrString* password){ char hmac[20]; char key[] = "Fluffy"; //char buffer[STUN_MAX_STRING]; computeHmac(hmac, username.value, strlen(username.value), key, strlen(key)); toHex(hmac, 20, password->value);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -