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

📄 stun.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 5 页
字号:
      ptr = encodeAtrRequestedTransport (ptr, &msg->requestedTransport);   }   if (msg->hasLifetimeAttributes)   {      ortp_debug("stun: Encoding TA_LIFETIME: %i\n", msg->lifetimeAttributes.lifetime );      ptr = encodeAtrLifeTime (ptr, &msg->lifetimeAttributes);   }   if (msg->hasDontFragment)   {      ortp_debug("stun: Encoding TA_DONTFRAGMENT: DF\n");      ptr = encodeAtrDontFragment (ptr);   }   if (msg->hasMappedAddress)   {      ortp_debug("stun: Encoding SA_MAPPEDADDRESS: %s\n", ipaddr(&msg->mappedAddress.ipv4) );      ptr = encodeAtrAddress4 (ptr, SA_MAPPEDADDRESS, &msg->mappedAddress);   }   if (msg->hasResponseAddress)   {      ortp_debug("stun: Encoding SA_RESPONSEADDRESS: %s\n", ipaddr(&msg->responseAddress.ipv4) );      ptr = encodeAtrAddress4(ptr, SA_RESPONSEADDRESS, &msg->responseAddress);   }   if (msg->hasChangeRequest)   {      ortp_debug("stun: Encoding SA_CHANGEREQUEST: %i\n", msg->changeRequest.value );      ptr = encodeAtrChangeRequest(ptr, &msg->changeRequest);   }   if (msg->hasSourceAddress)   {      ortp_debug("stun: Encoding SA_SOURCEADDRESS: %s\n", ipaddr(&msg->sourceAddress.ipv4) );      ptr = encodeAtrAddress4(ptr, SA_SOURCEADDRESS, &msg->sourceAddress);   }   if (msg->hasChangedAddress)   {      ortp_debug("stun: Encoding SA_CHANGEDADDRESS: %s\n", ipaddr(&msg->changedAddress.ipv4) );      ptr = encodeAtrAddress4(ptr, SA_CHANGEDADDRESS, &msg->changedAddress);   }   if (msg->hasUsername)   {      ortp_debug("stun: Encoding SA_USERNAME: %s\n", msg->username.value );      ptr = encodeAtrString(ptr, SA_USERNAME, &msg->username);   }   //if (msg->hasPassword)   //{   //   ortp_debug("stun: Encoding SA_PASSWORD: %s\n", msg->password.value );   //   ptr = encodeAtrString(ptr, SA_PASSWORD, &msg->password);   //}   if (msg->hasErrorCode)   {      ortp_debug("stun: Encoding SA_ERRORCODE: class=%i number=%i reason=%s\n"                           , msg->errorCode.errorClass                           , msg->errorCode.number                          , msg->errorCode.reason );            ptr = encodeAtrError(ptr, &msg->errorCode);   }   if (msg->hasUnknownAttributes)   {      ortp_debug("stun: Encoding SA_UNKNOWNATTRIBUTE: ???");      ptr = encodeAtrUnknown(ptr, &msg->unknownAttributes);   }   if (msg->hasReflectedFrom)   {      ortp_debug("stun: Encoding SA_REFLECTEDFROM: %s\n", ipaddr(&msg->reflectedFrom.ipv4) );      ptr = encodeAtrAddress4(ptr, SA_REFLECTEDFROM, &msg->reflectedFrom);   }   if (msg->hasNonce)   {      ortp_debug("stun: Encoding SA_NONCE: %s\n", msg->nonceName.value );      ptr = encodeAtrString(ptr, SA_NONCE, &msg->nonceName);   }   if (msg->hasRealm)   {      ortp_debug("stun: Encoding SA_REALM: %s\n", msg->realmName.value );      ptr = encodeAtrString(ptr, SA_REALM, &msg->realmName);   }      if (msg->hasXorMappedAddress)   {      ortp_debug("stun: Encoding SA_XORMAPPEDADDRESS: %s\n", ipaddr(&msg->xorMappedAddress.ipv4) );      ptr = encodeAtrAddress4 (ptr, SA_XORMAPPEDADDRESS, &msg->xorMappedAddress);   }   if (msg->hasSoftware)   {      ortp_debug("stun: Encoding SA_SOFTWARE: %s\n", msg->softwareName.value );      ptr = encodeAtrString(ptr, SA_SOFTWARE, &msg->softwareName);   }   if (msg->hasMessageIntegrity     &&password!=NULL && password->sizeValue > 0     &&msg->username.sizeValue>0     &&msg->realmName.sizeValue>0)   {      StunAtrIntegrity integrity;      //ortp_debug("stun: HMAC with password: %s\n", password->value );      encode16(lengthp, (UInt16)(ptr - buf - sizeof(StunMsgHdr)+24));      computeHmac_longterm(integrity.hash, buf, (int)(ptr-buf) ,        msg->username.value, msg->realmName.value, password->value);      ptr = encodeAtrIntegrity(ptr, &integrity);   }   else if (msg->hasMessageIntegrity     &&password!=NULL && password->sizeValue > 0     &&msg->username.sizeValue>0)   {      StunAtrIntegrity integrity;      //ortp_debug("stun: HMAC with password: %s\n", password->value );      encode16(lengthp, (UInt16)(ptr - buf - sizeof(StunMsgHdr)+24));      computeHmac_shortterm(integrity.hash, buf, (int)(ptr-buf) ,        password->value);      ptr = encodeAtrIntegrity(ptr, &integrity);   }	   encode16(lengthp, (UInt16)(ptr - buf - sizeof(StunMsgHdr)));   return (int)(ptr - buf);}int stunRand(void){   /* return 32 bits of random stuff */   /* assert( sizeof(int) == 4 ); */   static bool_t init=FALSE;   if ( !init )   {       UInt64 tick;      int seed;      init = TRUE;#if defined(_WIN32_WCE)      tick = GetTickCount ();#elif defined(_MSC_VER)      {      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(__GNUC__) && defined(__amd64__)      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);      }#elif defined(__linux) || defined(HAVE_DEV_RANDOM)       { 	fd_set fdSet;	int maxFd=0;	struct timeval tv;	int e;        int fd=open("/dev/random",O_RDONLY);	if (fd<0)	{	    ortp_message("stun: Failed to open random device\n");	    return random();	}        FD_ZERO(&fdSet);        FD_SET(fd,&fdSet);        maxFd=fd+1;	tv.tv_sec = 0;	tv.tv_usec = 500;	e = select( maxFd, &fdSet, NULL,NULL, &tv );	if (e <= 0)	{           ortp_error("stun: Failed to get data from random device\n");           closesocket(fd);	   return random();	}	read(fd,&tick,sizeof(tick));	closesocket(fd);      }#else#     error Need some way to seed the random number generator #endif       seed = (int)(tick);#if	defined(_WIN32) || defined(_WIN32_WCE)      srand(seed);#else      srandom(seed);#endif   }	#if	defined(_WIN32) || defined(_WIN32_WCE)   /* 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_longterm(char* hmac, const char* input, int length,                     const char *username, const char *realm, const char *password){   strncpy(hmac,"hmac-not-implemented",20);}static voidcomputeHmac_shortterm(char* hmac, const char* input, int length, const char* key){   strncpy(hmac,"hmac-not-implemented",20);}#else#include <openssl/hmac.h>#include <openssl/md5.h>static voidcomputeHmac_longterm(char* hmac, const char* input, int length,                     const char *username, const char *realm, const char *password){   unsigned int resultSize=0;   unsigned char HA1[16];   char HA1_text[1024];   snprintf(HA1_text, sizeof(HA1_text), "%s:%s:%s", username, realm, password);   MD5((unsigned char *)HA1_text, strlen(HA1_text), HA1);   HMAC(EVP_sha1(),         HA1, 16,         (const unsigned char*) input, length,         (unsigned char*)hmac, &resultSize);}static voidcomputeHmac_shortterm(char* hmac, const char* input, int length, const char* key){   unsigned int resultSize=0;   HMAC(EVP_sha1(),         key, strlen(key),         (const unsigned char*) input, length,         (unsigned char*)hmac, &resultSize);}#endifUInt64stunGetSystemTimeSecs(void){   UInt64 time=0;#if	defined(_WIN32) || defined(_WIN32_WCE)   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;}/* returns TRUE if it scucceeded */bool_t stunParseHostName( const char* peerName,                   UInt32* ip,                   UInt16* portVal,                   UInt16 defaultPort ){   struct in_addr sin_addr;       char host[512];   char* port = NULL;   int portNum = defaultPort;   char* sep;   struct hostent* h;   strncpy(host,peerName,512);   host[512-1]='\0';	   /* pull out the port part if present. */   sep = strchr(host,':');	   if ( sep == NULL )   {      portNum = defaultPort;   }   else   {      char* endPtr=NULL;      *sep = '\0';      port = sep + 1;      /* set port part */      		      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 */	#if	defined(_WIN32) || defined(_WIN32_WCE)   /* 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 ); */		      *ip = ntohl( a );   }   else   {      /* assume it is a host name */      h = gethostbyname( host );		      if ( h == NULL )      {         /*int err = getErrno();*/         /* ortp_message("stun: error was %i\n", err); */         /* 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();	 ortp_message("stun: error was %i\n", err);      */      *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_tstunParseServerName( const char* name, StunAddress4 *addr){   /* assert(name); */	   /* TODO - put in DNS SRV stuff. */	   bool_t 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 = (STUN_METHOD_BINDING | STUN_ERR_RESP);   response->hasErrorCode = TRUE;   response->errorCode.errorClass = cl;   response->errorCode.number = number;   strcpy(response->errorCode.reason, 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);}#endif#if 0static voidstunCreateSharedSecretResponse(const StunMessage *request, const StunAddress4 *source, StunMessage *response){   response->msgHdr.msgType = SharedSecretResponseMsg;   response->msgHdr.tr_id = request->msgHdr.tr_id;	   response->hasUsername = TRUE;   stunCreateUserName( source, &response->username);	   response->hasPassword = TRUE;   stunCreatePassword( &response->username, &response->password);}#endif/* This funtion takes a single message sent to a stun server, parses   and constructs an apropriate repsonse - returns TRUE if message is   valid */bool_tstunServerProcessMsg( char* buf,                      unsigned int bufLen,                      StunAddress4 *from,                       StunAddress4 *myAddr,                      StunAddress4 *altAddr,                       StunMessage *resp,                      StunAddress4 *destination,                      StunAtrString *hmacPassword,                      bool_t* changePort,                      bool_t* changeIp){   int i;   StunMessage req;   StunAddress4 mapped;   StunAddress4 respondTo;   UInt32 flags;   bool_t ok;

⌨️ 快捷键说明

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