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

📄 stun.cxx

📁 现在应用最广泛的一种私网穿透方式
💻 CXX
📖 第 1 页 / 共 5 页
字号:
      tv.tv_usec=150*1000; // 150 ms       if ( count == 0 ) tv.tv_usec=0;		      int  err = select(fdSetSize, &fdSet, NULL, NULL, &tv);      int e = getErrno();      if ( err == SOCKET_ERROR )      {         // error occured         cerr << "Error " << e << " " << strerror(e) << " in select" << endl;        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      {         //if (verbose) clog << "-----------------------------------------" << endl;         assert( err>0 );         // data is avialbe on some fd 			         for ( int 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;						                  getMessage( myFd,                              msg,                              &msgLen,                              &from.addr,                              &from.port,verbose );						                  StunMessage resp;                  memset(&resp, 0, sizeof(StunMessage));						                  stunParseMessage( msg,msgLen, resp,verbose );						                  if ( verbose )                  {                     clog << "Received message of type " << resp.msgHdr.msgType                           << "  id=" << (int)(resp.msgHdr.id.octet[0]) << endl;                  }						                  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:                     {							                        if ( hairpin )                         {                           *hairpin = true;                        }                        respTestHairpin = true;                     }                     break;                  }               }            }         }      }   }	   // see if we can bind to this address    //cerr << "try binding to " << testImappedAddr << endl;   Socket s = openPort( 0/*use ephemeral*/, testImappedAddr.addr, false );   if ( s != INVALID_SOCKET )   {      closesocket(s);      isNat = false;      //cerr << "binding worked" << endl;   }   else   {      isNat = true;      //cerr << "binding failed" << endl;   }	   if (verbose)   {      clog << "test I = " << respTestI << endl;      clog << "test II = " << respTestII << endl;      clog << "test III = " << respTestIII << endl;      clog << "test I(2) = " << respTestI2 << endl;      clog << "is nat  = " << isNat <<endl;      clog << "mapped IP same = " << mappedIpSame << endl;   }	   // implement logic flow chart from draft RFC   if ( respTestI )   {      if ( isNat )      {         if (respTestII)         {            return StunTypeConeNat;         }         else         {            if ( mappedIpSame )            {               if ( respTestIII )               {                  return StunTypeRestrictedNat;               }               else               {                  return StunTypePortRestrictedNat;               }            }            else            {               return StunTypeSymNat;            }         }      }      else      {         if (respTestII)         {            return StunTypeOpen;         }         else         {            return StunTypeSymFirewall;         }      }   }   else   {      return StunTypeBlocked;   }	   return StunTypeUnknown;}intstunOpenSocket( StunAddress4& dest, StunAddress4* mapAddr,                 int port, StunAddress4* srcAddr,                 bool verbose ){   assert( dest.addr != 0 );   assert( dest.port != 0 );   assert( mapAddr );      if ( port == 0 )   {      port = randomPort();   }   unsigned int interfaceIp = 0;   if ( srcAddr )   {      interfaceIp = srcAddr->addr;   }      Socket myFd = openPort(port,interfaceIp,verbose);   if (myFd == INVALID_SOCKET)   {      return myFd;   }      char msg[STUN_MAX_MESSAGE_SIZE];   int msgLen = sizeof(msg);	   StunAtrString username;   StunAtrString password;	   username.sizeValue = 0;   password.sizeValue = 0;	#ifdef USE_TLS   stunGetUserNameAndPassword( dest, username, password );#endif	   stunSendTest(myFd, dest, username, password, 1, 0/*false*/ );	   StunAddress4 from;	   getMessage( myFd, msg, &msgLen, &from.addr, &from.port,verbose );	   StunMessage resp;   memset(&resp, 0, sizeof(StunMessage));	   bool ok = stunParseMessage( msg, msgLen, resp,verbose );   if (!ok)   {      return -1;   }	   StunAddress4 mappedAddr = resp.mappedAddress.ipv4;   StunAddress4 changedAddr = resp.changedAddress.ipv4;	   //clog << "--- stunOpenSocket --- " << endl;   //clog << "\treq  id=" << req.id << endl;   //clog << "\tresp id=" << id << endl;   //clog << "\tmappedAddr=" << mappedAddr << endl;	   *mapAddr = mappedAddr;	   return myFd;}boolstunOpenSocketPair( StunAddress4& dest, StunAddress4* mapAddr,                     int* fd1, int* fd2,                     int port, StunAddress4* srcAddr,                     bool verbose ){   assert( dest.addr!= 0 );   assert( dest.port != 0 );   assert( mapAddr );      const int NUM=3;	   if ( port == 0 )   {      port = randomPort();   }	   *fd1=-1;   *fd2=-1;	   char msg[STUN_MAX_MESSAGE_SIZE];   int msgLen =sizeof(msg);	   StunAddress4 from;   int fd[NUM];   int i;	   unsigned int interfaceIp = 0;   if ( srcAddr )   {      interfaceIp = srcAddr->addr;   }   for( i=0; i<NUM; i++)   {      fd[i] = openPort( (port == 0) ? 0 : (port + i),                         interfaceIp, verbose);      if (fd[i] < 0)       {         while (i > 0)         {            closesocket(fd[--i]);         }         return false;      }   }	   StunAtrString username;   StunAtrString password;	   username.sizeValue = 0;   password.sizeValue = 0;	#ifdef USE_TLS   stunGetUserNameAndPassword( dest, username, password );#endif	   for( i=0; i<NUM; i++)   {      stunSendTest(fd[i], dest, username, password, 1/*testNum*/, verbose );   }	   StunAddress4 mappedAddr[NUM];   for( i=0; i<NUM; i++)   {      msgLen = sizeof(msg)/sizeof(*msg);      getMessage( fd[i],                  msg,                  &msgLen,                  &from.addr,                  &from.port ,verbose);		      StunMessage resp;      memset(&resp, 0, sizeof(StunMessage));		      bool ok = stunParseMessage( msg, msgLen, resp, verbose );      if (!ok)       {         return false;      }		      mappedAddr[i] = resp.mappedAddress.ipv4;      StunAddress4 changedAddr = resp.changedAddress.ipv4;   }	   if (verbose)   {                     clog << "--- stunOpenSocketPair --- " << endl;      for( i=0; i<NUM; i++)      {         clog << "\t mappedAddr=" << mappedAddr[i] << endl;      }   }	   if ( mappedAddr[0].port %2 == 0 )   {      if (  mappedAddr[0].port+1 ==  mappedAddr[1].port )      {         *mapAddr = mappedAddr[0];         *fd1 = fd[0];         *fd2 = fd[1];         closesocket( fd[2] );         return true;      }   }   else   {      if (( mappedAddr[1].port %2 == 0 )          && (  mappedAddr[1].port+1 ==  mappedAddr[2].port ))      {         *mapAddr = mappedAddr[1];         *fd1 = fd[1];         *fd2 = fd[2];         closesocket( fd[0] );         return true;      }   }   // something failed, close all and return error   for( i=0; i<NUM; i++)   {      closesocket( fd[i] );   }	   return false;}/* ==================================================================== * The Vovida Software License, Version 1.0  *  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. *  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. *  * 3. The names "VOCAL", "Vovida Open Communication Application Library", *    and "Vovida Open Communication Application Library (VOCAL)" must *    not be used to endorse or promote products derived from this *    software without prior written permission. For written *    permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor *    may "VOCAL" appear in their name, without prior written *    permission of Vovida Networks, Inc. *  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. *  * ==================================================================== *  * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc.  For

⌨️ 快捷键说明

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