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

📄 stun.cxx

📁 这是国外的resip协议栈
💻 CXX
📖 第 1 页 / 共 5 页
字号:
   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;}ostream&operator<<(ostream& os, const StunMsgHdr& h){   os << "STUN: ";   switch (h.msgType) {      case BindRequestMsg:            os << "BindingRequest";         break;      case BindResponseMsg:            os << "BindingResponse";         break;      case BindErrorResponseMsg:            os << "BindingErrorResponse";         break;		case TurnAllocateRequest:            os << "TurnAllocateRequest";			break;		case TurnAllocateResponse:            os << "TurnAllocateResponse";			break;		case TurnAllocateErrorResponse:            os << "TurnAllocateErrorResponse";			break;		case TurnSendRequest:            os << "TurnSendRequest";			break;		case TurnSendResponse:            os << "TurnSendResponse";			break;		case TurnSendErrorResponse:            os << "TurnSendErrorResponse";			break;		case TurnDataIndication:            os << "TurnDataIndication";			break;		case TurnSetActiveDestinationRequest:            os << "TurnSetActiveDestinationRequest";			break;		case TurnSetActiveDestinationResponse:            os << "TurnSetActiveDestinationResponse";			break;		case TurnSetActiveDestinationErrorResponse:            os << "TurnSetActiveDestinationErrorResponse";      break;   }    os << ", id ";    os << std::hex;    for (unsigned int i = 0; i < sizeof(UInt128); i++) {        os << static_cast<int>(h.id.octet[i]);    }    os << std::dec;    return os;}// 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;}static voidstunCreateErrorResponse(StunMessage& response, int cl, int number, const char* msg){   response.msgHdr.msgType = BindErrorResponseMsg;   response.hasErrorCode = true;   response.errorCode.errorClass = cl;   response.errorCode.number = number;   strcpy(response.errorCode.reason, msg);   response.errorCode.sizeReason = strlen(msg);}#if 0static voidstunCreateSharedSecretErrorResponse(StunMessage& response, int cl, int number, const char* msg){   response.msgHdr.msgType = SharedSecretErrorResponseMsg;   response.hasErrorCode = true;   response.errorCode.errorClass = cl;   response.errorCode.number = number;   strcpy(response.errorCode.reason, msg);}#endifstatic voidstunCreateSharedSecretResponse(const StunMessage& request, const StunAddress4& source, StunMessage& response){   response.msgHdr.msgType = SharedSecretResponseMsg;   response.msgHdr.id = request.msgHdr.id;	   response.hasUsername = true;   stunCreateUserName( source, &response.username);	   response.hasPassword = true;   stunCreatePassword( response.username, &response.password);}// This funtion takes a single message sent to a stun server, parses// and constructs an apropriate repsonse - returns true if message is// validboolstunServerProcessMsg( char* buf,                      unsigned int bufLen,                      StunAddress4& from,                       StunAddress4& secondary,                      StunAddress4& myAddr,                      StunAddress4& altAddr,                       StunMessage* resp,                      StunAddress4* destination,                      StunAtrString* hmacPassword,                      bool* changePort,                      bool* changeIp,                      bool verbose){       // set up information for default response 	   memset( resp, 0 , sizeof(*resp) );	   *changeIp = false;   *changePort = false;	   StunMessage req;   bool ok = stunParseMessage( buf,bufLen, req, verbose);	   if (!ok)      // Complete garbage, drop it on the floor   {      if (verbose) clog << "Request did not parse" << endl;      return false;   }   if (verbose) clog << "Request parsed ok" << endl;	   StunAddress4 mapped = req.mappedAddress.ipv4;   StunAddress4 respondTo = req.responseAddress.ipv4;   UInt32 flags = req.changeRequest.value;	   switch (req.msgHdr.msgType)   {      case SharedSecretRequestMsg:         if(verbose) clog << "Received SharedSecretRequestMsg on udp. send error 433." << endl;         // !cj! - should fix so you know if this came over TLS or UDP         stunCreateSharedSecretResponse(req, from, *resp);         //stunCreateSharedSecretErrorResponse(*resp, 4, 33, "this request must be over TLS");         return true;			      case BindRequestMsg:         if (!req.hasMessageIntegrity)         {            if (verbose) clog << "BindRequest does not contain MessageIntegrity" << endl;				            if (0) // !jf! mustAuthenticate            {               if(verbose) clog << "Received BindRequest with no MessageIntegrity. Sending 401." << endl;               stunCreateErrorResponse(*resp, 4, 1, "Missing MessageIntegrity");               return true;            }         }         else         {            if (!req.hasUsername)            {               if (verbose) clog << "No UserName. Send 432." << endl;               stunCreateErrorResponse(*resp, 4, 32, "No UserName and contains MessageIntegrity");               return true;            }            else            {               if (verbose) clog << "Validating username: " << req.username.value << endl;               // !jf! could retrieve associated password from provisioning here               if (strcmp(req.username.value, "test") == 0)               {                  if (0)                  {                     // !jf! if the credentials are stale                      stunCreateErrorResponse(*resp, 4, 30, "Stale credentials on BindRequest");                     return true;                  }                  else                  {                     if (verbose) clog << "Validating MessageIntegrity" << endl;                     // need access to shared secret							                     unsigned char hmac[20];#ifdef USE_SSL                     unsigned int hmacSize=20;                     HMAC(EVP_sha1(),                           "1234", 4,                           reinterpret_cast<const unsigned char*>(buf), bufLen-20-4,                           hmac, &hmacSize);                     assert(hmacSize == 20);#endif							                     if (memcmp(buf, hmac, 20) != 0)                     {                        if (verbose) clog << "MessageIntegrity is bad. Sending " << endl;                        stunCreateErrorResponse(*resp, 4, 3, "Unknown username. Try test with password 1234");                        return true;                     }							                     // need to compute this later after message is filled in                     resp->hasMessageIntegrity = true;                     assert(req.hasUsername);                     resp->hasUsername = true;                     resp->username = req.username; // copy username in                  }               }               else               {                  if (verbose) clog << "Invalid username: " << req.username.value << "Send 430." << endl;                }            }         }			         // TODO !jf! should check for unknown attributes here and send 420 listing the         // unknown attributes. 			         if ( respondTo.port == 0 ) respondTo = from;         if ( mapped.port == 0 ) mapped = from;				         *changeIp   = ( flags & ChangeIpFlag )?true:false;         *changePort = ( flags & ChangePortFlag )?true:false;			         if (verbose)         {            clog << "Request is valid:" << endl;            clog << "\t flags=" << flags << endl;            clog << "\t changeIp=" << *changeIp << endl;            clog << "\t changePort=" << *changePort << endl;            clog << "\t from = " << from << endl;            clog << "\t respond to = " << respondTo << endl;            clog << "\t mapped = " << mapped << endl;         }				         // form the outgoing message         resp->msgHdr.msgType = BindResponseMsg;         for ( int i=0; i<16; i++ )         {            resp->msgHdr.id.octet[i] = req.msgHdr.id.octet[i];         }		         if ( req.xorOnly == false )         {            resp->hasMappedAddress = true;            resp->mappedAddress.ipv4.port = mapped.port;            resp->mappedAddress.ipv4.addr = mapped.addr;         }         if (1) // do xorMapped address or not          {            resp->hasXorMappedAddress = true;            UInt16 id16 = req.msgHdr.id.octet[0]<<8                | req.msgHdr.id.octet[1];            UInt32 id32 = req.msgHdr.id.octet[0]<<24                | req.msgHdr.id.octet[1]<<16                | req.msgHdr.id.octet[2]<<8                | req.msgHdr.id.octet[3];            resp->xorMappedAddress.ipv4.port = mapped.port^id16;            resp->xorMappedAddress.ipv4.addr = mapped.addr^id32;         }                  resp->hasSourceAddress = true;         resp->sourceAddress.ipv4.port = (*changePort) ? altAddr.port : myAddr.port;         resp->sourceAddress.ipv4.addr = (*changeIp)   ? altAddr.addr : myAddr.addr;			         resp->hasChangedAddress = true;         resp->changedAddress.ipv4.port = altAddr.port;         resp->changedAddress.ipv4.addr = altAddr.addr;	         if ( secondary.port != 0 )         {            resp->hasSecondaryAddress = true;            resp->secondaryAddress.ipv4.port = secondary.port;            resp->secondaryAddress.ipv4.addr = secondary.addr;         }                  if ( req.hasUsername && req.username.sizeValue > 0 )          {            // copy username in            resp->hasUsername = true;            assert( req.username.sizeValue % 4 == 0 );            assert( req.username.sizeValue < STUN_MAX_STRING );            memcpy( resp->username.value, req.username.value, req.username.sizeValue );            resp->username.sizeValue = req.username.sizeValue;         }		         if (1) // add ServerName          {            resp->hasServerName = true;            const char serverName[] = "Vovida.org " STUN_VERSION; // must pad to mult of 4                        assert( sizeof(serverName) < STUN_MAX_STRING );            //cerr << "sizeof serverName is "  << sizeof(serverName) << endl;            assert( sizeof(serverName)%4 == 0 );            memcpy( resp->serverName.value, serverName, sizeof(serverName));            resp->serverName.sizeValue = sizeof(serverName);         }                  if ( req.hasMessageIntegrity & req.hasUsername )           {            // this creates the password that will be used in the HMAC when then            // messages is sent            stunCreatePassword( req.username, hmacPassword );         }				         if (req.hasUsername && (req.username.sizeValue > 64 ) )         {            UInt32 source;            assert( sizeof(int) == sizeof(UInt32) );					            sscanf(req.username.value, "%x", &source);            resp->hasReflectedFrom = true;            resp->reflectedFrom.ipv4.port = 0;

⌨️ 快捷键说明

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