⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stun.cxx

📁 现在应用最广泛的一种私网穿透方式
💻 CXX
📖 第 1 页 / 共 5 页
字号:
   ptr = encode16(ptr, 6 + 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;	   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 stunRand(){   // return 32 bits of random stuff   assert( sizeof(int) == 4 );   static bool init=false;   if ( !init )   {       init = true;		      UInt64 tick;		#if defined(WIN32)       volatile unsigned int lowtick=0,hightick=0;      __asm         {            rdtsc                mov lowtick, eax               mov hightick, edx               }      tick = hightick;      tick <<= 32;      tick |= lowtick;#elif defined(__GNUC__) && ( defined(__i686__) || defined(__i386__) )      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));      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 static intrandomPort(){   int min=0x4000;   int max=0x7FFF;	   int ret = stunRand();   ret = ret|min;   ret = ret&max;	   return ret;}#ifdef NOSSLstatic voidcomputeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey){   strncpy(hmac,"hmac-not-implemented",20);}#else#include <openssl/hmac.h>static 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);   password->sizeValue = 40;   password->value[40]=0;	   //clog << "password=" << password->value << endl;}UInt64stunGetSystemTimeSecs(){   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;}ostream& operator<< ( ostream& strm, const UInt128& r ){   strm << int(r.octet[0]);   for ( int i=1; i<16; i++ )   {      strm << ':' << int(r.octet[i]);   }       return strm;}ostream& operator<<( ostream& strm, const StunAddress4& addr){   UInt32 ip = addr.addr;   strm << ((int)(ip>>24)&0xFF) << ".";   strm << ((int)(ip>>16)&0xFF) << ".";   strm << ((int)(ip>> 8)&0xFF) << ".";   strm << ((int)(ip>> 0)&0xFF) ;	   strm << ":" << addr.port;	   return strm;}// returns true if it scucceededbool stunParseHostName( char* peerName,               UInt32& ip,               UInt16& portVal,               UInt16 defaultPort ){   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;}boolstunParseServerName( char* name, StunAddress4& addr){   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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -