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

📄 stun.c

📁 linphone的最新版本
💻 C
📖 第 1 页 / 共 5 页
字号:
                    bool_t changePort, bool_t changeIp, unsigned int id ){   int i;   /* assert( msg ); */   memset( msg , 0 , sizeof(*msg) );	   msg->msgHdr.msgType = BindRequestMsg;	   for ( 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; */      memcpy(&msg->username, username, sizeof(StunAtrString));   }}static void stunSendTest( Socket myFd, StunAddress4 *dest,               const StunAtrString *username, const StunAtrString *password,               int testNum, bool_t verbose ){    /* assert( dest.addr != 0 ); */   /* assert( dest.port != 0 ); */	   bool_t changePort=FALSE;   bool_t changeIP=FALSE;   bool_t discard=FALSE;   StunMessage req;   char buf[STUN_MAX_MESSAGE_SIZE];   int len = STUN_MAX_MESSAGE_SIZE;      switch (testNum)   {      case 1:      case 10:      case 11:         break;      case 2:         /* changePort=TRUE; */         changeIP=TRUE;         break;      case 3:         changePort=TRUE;         break;      case 4:         changeIP=TRUE;         break;      case 5:         discard=TRUE;         break;      default:         ortp_error("stun: Test %i is unkown\n", testNum);         return ; /* error */   }      memset(&req, 0, sizeof(StunMessage));	   stunBuildReqSimple( &req, username,                        changePort , changeIP ,                        testNum );	   len = stunEncodeMessage( &req, buf, len, password,verbose );	   if ( verbose )   {      ortp_message("stun: About to send msg of len %i to %s\n", len, ipaddr(dest) );   }	   sendMessage( myFd, buf, len, dest->addr, dest->port, verbose );	   /* add some delay so the packets don't get sent too quickly */#if defined(_WIN32_WCE)    Sleep (10);#elif defined(WIN32)/* !cj! TODO - should fix this up in windows */   {       clock_t now = clock();       /* assert( CLOCKS_PER_SEC == 1000 ); */       while ( clock() <= now+10 ) { };   }#else		 usleep(10*1000);#endif}void stunGetUserNameAndPassword(  const StunAddress4 *dest,                              StunAtrString* username,                             StunAtrString* password){    /* !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);}int stunTest( StunAddress4 *dest, int testNum, bool_t verbose, StunAddress4* sAddr , StunAddress4 *sMappedAddr, StunAddress4* sChangedAddr){   /* assert( dest.addr != 0 ); */   /* assert( dest.port != 0 ); */	   int port = randomPort();   UInt32 interfaceIp=0;   Socket myFd;   StunAtrString username;   StunAtrString password;   char msg[STUN_MAX_MESSAGE_SIZE];   int msgLen = STUN_MAX_MESSAGE_SIZE;   StunAddress4 from;   StunMessage resp;   bool_t ok;   if (sAddr)   {      interfaceIp = sAddr->addr;      if ( sAddr->port != 0 )      {        port = sAddr->port;      }   }   myFd = openPort(port,interfaceIp,verbose);   if ( myFd == INVALID_SOCKET)       return -1;      username.sizeValue = 0;   password.sizeValue = 0;	#ifdef USE_TLS   stunGetUserNameAndPassword( dest, &username, &password );#endif	   stunSendTest( myFd, dest, &username, &password, testNum, verbose );      ok = getMessage( myFd,               msg,               &msgLen,               &from.addr,               &from.port,verbose );   closesocket(myFd);   if (!ok)       return -1;   memset(&resp, 0, sizeof(StunMessage));	   if ( verbose ) ortp_message("stun: Got a response");   ok = stunParseMessage( msg,msgLen, &resp,verbose );	   if ( verbose )   {      ortp_message("stun: \t ok=%i\n", ok );#if defined(WIN32) || defined(_WIN32_WCE)      ortp_message("stun: \t id=%u\n", *(unsigned int*)&resp.msgHdr.id );#endif      ortp_message("stun: \t mappedAddr=%i\n", resp.mappedAddress.ipv4.addr );      ortp_message("stun: \t changedAddr=%i\n", resp.changedAddress.ipv4.addr );   }	   if (sAddr)   {       sAddr->port = port;   }   if (sMappedAddr)   {      sMappedAddr->port = resp.mappedAddress.ipv4.port;      sMappedAddr->addr = resp.mappedAddress.ipv4.addr;   }   if (sChangedAddr)   {      sChangedAddr->port = resp.changedAddress.ipv4.port;      sChangedAddr->addr = resp.changedAddress.ipv4.addr;   }   if (ok)       return 0;   else       return -1;}NatTypestunNatType( StunAddress4 *dest,              bool_t verbose,             bool_t* preservePort, /* if set, is return for if NAT preservers ports or not */             bool_t* hairpin,  /* if set, is the return for if NAT will hairpin packets */             int port, /* port to use for the test, 0 to choose random port */             StunAddress4* sAddr /* NIC to use */   ){    /* assert( dest.addr != 0 ); */   /* assert( dest.port != 0 ); */   UInt32 interfaceIp=0;   Socket myFd1;   Socket myFd2;   bool_t respTestI=FALSE;   bool_t isNat=TRUE;   StunAddress4 testIchangedAddr;   StunAddress4 testImappedAddr;   bool_t respTestI2=FALSE;    bool_t mappedIpSame = TRUE;   StunAddress4 testI2mappedAddr;   /* StunAddress4 testI2dest=dest; */   StunAddress4 testI2dest;   bool_t respTestII=FALSE;   bool_t respTestIII=FALSE;   bool_t respTestHairpin=FALSE;   StunAtrString username;   StunAtrString password;   int count=0;   UInt64 second_started;   UInt64 second_elapsed;   Socket s;   if ( hairpin )    {      *hairpin = FALSE;   }	   if ( port == 0 )   {      port = randomPort();   }   if (sAddr)   {      interfaceIp = sAddr->addr;   }   myFd1 = openPort(port,interfaceIp,verbose);   myFd2 = openPort(port+1,interfaceIp,verbose);   if ( ( myFd1 == INVALID_SOCKET) || ( myFd2 == INVALID_SOCKET) )   {      ortp_error("stun: Some problem opening port/interface to send on\n");      return StunTypeFailure;    }   /* assert( myFd1 != INVALID_SOCKET ); */   /* assert( myFd2 != INVALID_SOCKET ); */      memcpy(&testI2dest, dest, sizeof(StunAddress4));   memset(&testImappedAddr,0,sizeof(testImappedAddr));      username.sizeValue = 0;   password.sizeValue = 0;	#ifdef USE_TLS    stunGetUserNameAndPassword( dest, username, password );#endif	   /* stunSendTest( myFd1, dest, username, password, 1, verbose ); */      second_started = stunGetSystemTimeSecs();   second_elapsed = 1;   while ( count < 7 && second_elapsed < 5)   {      struct timeval tv;      fd_set fdSet;       int err;      int e;#if defined(WIN32) || defined(_WIN32_WCE)      unsigned int fdSetSize;#else      int fdSetSize;#endif      second_elapsed = stunGetSystemTimeSecs() - second_started ;      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=500*1000; /* 150 ms */      if ( count == 0 ) tv.tv_usec=0;		      err = select(fdSetSize, &fdSet, NULL, NULL, &tv);      e = getErrno();      if ( err == SOCKET_ERROR )      {         /* error occured */#if !defined(_WIN32_WCE)         ortp_error("stun: Error %i %s in select\n", e, strerror(e));#else         ortp_error("stun: Error %i in select\n", e);#endif		 closesocket(myFd1); /* AMD */         closesocket(myFd2); /* AMD */         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      {         int i;         /* if (verbose) ortp_message("stun: -----------------------------------------"); */         /* assert( err>0 ); */         /* data is avialbe on some fd */			         for ( i=0; i<2; i++)         {            Socket myFd;            if ( i==0 )             {               myFd=myFd1;            }            else            {               myFd=myFd2;            }				            if ( myFd!=INVALID_SOCKET )             {					               if ( FD_ISSET(myFd,&fdSet) )               {                  char msg[STUN_MAX_MESSAGE_SIZE];                  int msgLen = sizeof(msg);                  						                  StunAddress4 from;                  StunMessage resp;                  getMessage( myFd,                              msg,                              &msgLen,                              &from.addr,                              &from.port,verbose );                                    memset(&resp, 0, sizeof(StunMessage));						                  stunParseMessage( msg,msgLen, &resp,verbose );						                  if ( verbose )                  {                     ortp_message("stun: Received message of type %i id=%i\n",                            resp.msgHdr.msgType,                            (int)(resp.msgHdr.id.octet[0]) );                  }						                  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;									                           if ( preservePort )                           {                              *preservePort = ( testImappedAddr.port == port );                           }																	                           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:

⌨️ 快捷键说明

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