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

📄 stun.cxx

📁 现在应用最广泛的一种私网穿透方式
💻 CXX
📖 第 1 页 / 共 5 页
字号:
      {         if (verbose) clog << "received on A1:P2" << endl;         recvAltIp = false;         recvAltPort = true;         ok = getMessage( info.altPortFd, msg, &msgLen, &from.addr, &from.port,verbose );      }      else if ( (info.altIpFd!=INVALID_SOCKET) && FD_ISSET(info.altIpFd,&fdSet))      {         if (verbose) clog << "received on A2:P1" << endl;         recvAltIp = true;         recvAltPort = false;         ok = getMessage( info.altIpFd, msg, &msgLen, &from.addr, &from.port ,verbose);      }      else if ( (info.altIpPortFd!=INVALID_SOCKET) && FD_ISSET(info.altIpPortFd, &fdSet))      {         if (verbose) clog << "received on A2:P2" << endl;         recvAltIp = true;         recvAltPort = true;         ok = getMessage( info.altIpPortFd, msg, &msgLen, &from.addr, &from.port,verbose );      }      else      {         return true;      }      int relayPort = 0;      if (info.relay)      {         for (int i=0; i<MAX_MEDIA_RELAYS; ++i)         {            StunMediaRelay* relay = &info.relays[i];            if (relay->destination.addr == from.addr &&                 relay->destination.port == from.port)            {               relayPort = relay->relayPort;               relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT;               break;            }         }         if (relayPort == 0)         {            for (int i=0; i<MAX_MEDIA_RELAYS; ++i)            {               StunMediaRelay* relay = &info.relays[i];               if (relay->fd == 0)               {                  if ( verbose ) clog << "Open relay port " << relay->relayPort << endl;                                    relay->fd = openPort(relay->relayPort, info.myAddr.addr, verbose);                  relay->destination.addr = from.addr;                  relay->destination.port = from.port;                  relay->expireTime = time(0) + MEDIA_RELAY_TIMEOUT;                  relayPort = relay->relayPort;                  break;               }            }         }      }               if ( !ok )       {         if ( verbose ) clog << "Get message did not return a valid message" <<endl;         return true;      }		      if ( verbose ) clog << "Got a request (len=" << msgLen << ") from " << from << endl;		      if ( msgLen <= 0 )      {         return true;      }		      bool changePort = false;      bool changeIp = false;		      StunMessage resp;      StunAddress4 dest;      StunAtrString hmacPassword;        hmacPassword.sizeValue = 0;      StunAddress4 secondary;      secondary.port = 0;      secondary.addr = 0;                     if (info.relay && relayPort)      {         secondary = from;                  from.addr = info.myAddr.addr;         from.port = relayPort;      }            ok = stunServerProcessMsg( msg, msgLen, from, secondary,                                 recvAltIp ? info.altAddr : info.myAddr,                                 recvAltIp ? info.myAddr : info.altAddr,                                  &resp,                                 &dest,                                 &hmacPassword,                                 &changePort,                                 &changeIp,                                 verbose );		      if ( !ok )      {         if ( verbose ) clog << "Failed to parse message" << endl;         return true;      }		      char buf[STUN_MAX_MESSAGE_SIZE];      int len = sizeof(buf);      		      len = stunEncodeMessage( resp, buf, len, hmacPassword,verbose );		      if ( dest.addr == 0 )  ok=false;      if ( dest.port == 0 ) ok=false;		      if ( ok )      {         assert( dest.addr != 0 );         assert( dest.port != 0 );			         Socket sendFd;			         bool sendAltIp   = recvAltIp;   // send on the received IP address          bool sendAltPort = recvAltPort; // send on the received port			         if ( changeIp )   sendAltIp   = !sendAltIp;   // if need to change IP, then flip logic          if ( changePort ) sendAltPort = !sendAltPort; // if need to change port, then flip logic 			         if ( !sendAltPort )         {            if ( !sendAltIp )            {               sendFd = info.myFd;            }            else            {               sendFd = info.altIpFd;            }         }         else         {            if ( !sendAltIp )            {               sendFd = info.altPortFd;            }            else            {               sendFd = info.altIpPortFd;            }         }	         if ( sendFd != INVALID_SOCKET )         {            sendMessage( sendFd, buf, len, dest.addr, dest.port, verbose );         }      }   }	   return true;}int stunFindLocalInterfaces(UInt32* addresses,int maxRet){#if defined(WIN32) || defined(__sparc__)   return 0;#else   struct ifconf ifc;	   int s = socket( AF_INET, SOCK_DGRAM, 0 );   int len = 100 * sizeof(struct ifreq);	   char buf[ len ];	   ifc.ifc_len = len;   ifc.ifc_buf = buf;	   int e = ioctl(s,SIOCGIFCONF,&ifc);   char *ptr = buf;   int tl = ifc.ifc_len;   int count=0;	   while ( (tl > 0) && ( count < maxRet) )   {      struct ifreq* ifr = (struct ifreq *)ptr;		      int si = sizeof(ifr->ifr_name) + sizeof(struct sockaddr);      tl -= si;      ptr += si;      //char* name = ifr->ifr_ifrn.ifrn_name;      //cerr << "name = " << name << endl;		      struct ifreq ifr2;      ifr2 = *ifr;		      e = ioctl(s,SIOCGIFADDR,&ifr2);      if ( e == -1 )      {         break;      }		      //cerr << "ioctl addr e = " << e << endl;		      struct sockaddr a = ifr2.ifr_addr;      struct sockaddr_in* addr = (struct sockaddr_in*) &a;		      UInt32 ai = ntohl( addr->sin_addr.s_addr );      if (int((ai>>24)&0xFF) != 127)      {         addresses[count++] = ai;      }		#if 0      cerr << "Detected interface "           << int((ai>>24)&0xFF) << "."            << int((ai>>16)&0xFF) << "."            << int((ai>> 8)&0xFF) << "."            << int((ai    )&0xFF) << endl;#endif   }	   closesocket(s);	   return count;#endif}voidstunBuildReqSimple( StunMessage* msg,                    const StunAtrString& username,                    bool changePort, bool changeIp, unsigned int id ){   assert( msg );   memset( msg , 0 , sizeof(*msg) );	   msg->msgHdr.msgType = BindRequestMsg;	   for ( int 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;   }}static void stunSendTest( Socket myFd, StunAddress4& dest,               const StunAtrString& username, const StunAtrString& password,               int testNum, bool verbose ){    assert( dest.addr != 0 );   assert( dest.port != 0 );	   bool changePort=false;   bool changeIP=false;   bool discard=false;	   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:         cerr << "Test " << testNum <<" is unkown\n";         assert(0);   }	   StunMessage req;   memset(&req, 0, sizeof(StunMessage));	   stunBuildReqSimple( &req, username,                        changePort , changeIP ,                        testNum );	   char buf[STUN_MAX_MESSAGE_SIZE];   int len = STUN_MAX_MESSAGE_SIZE;	   len = stunEncodeMessage( req, buf, len, password,verbose );	   if ( verbose )   {      clog << "About to send msg of len " << len << " to " << dest << endl;   }	   sendMessage( myFd, buf, len, dest.addr, dest.port, verbose );	   // add some delay so the packets don't get sent too quickly #ifdef 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);}void stunTest( StunAddress4& dest, int testNum, bool verbose, StunAddress4* sAddr ){    assert( dest.addr != 0 );   assert( dest.port != 0 );	   int port = randomPort();   UInt32 interfaceIp=0;   if (sAddr)   {      interfaceIp = sAddr->addr;      if ( sAddr->port != 0 )      {        port = sAddr->port;      }   }   Socket myFd = openPort(port,interfaceIp,verbose);	   StunAtrString username;   StunAtrString password;	   username.sizeValue = 0;   password.sizeValue = 0;	#ifdef USE_TLS   stunGetUserNameAndPassword( dest, username, password );#endif	   stunSendTest( myFd, dest, username, password, testNum, verbose );       char msg[STUN_MAX_MESSAGE_SIZE];   int msgLen = STUN_MAX_MESSAGE_SIZE;	   StunAddress4 from;   getMessage( myFd,               msg,               &msgLen,               &from.addr,               &from.port,verbose );	   StunMessage resp;   memset(&resp, 0, sizeof(StunMessage));	   if ( verbose ) clog << "Got a response" << endl;   bool ok = stunParseMessage( msg,msgLen, resp,verbose );	   if ( verbose )   {      clog << "\t ok=" << ok << endl;      clog << "\t id=" << resp.msgHdr.id << endl;      clog << "\t mappedAddr=" << resp.mappedAddress.ipv4 << endl;      clog << "\t changedAddr=" << resp.changedAddress.ipv4 << endl;      clog << endl;   }	   if (sAddr)   {      sAddr->port = resp.mappedAddress.ipv4.port;      sAddr->addr = resp.mappedAddress.ipv4.addr;   }}NatTypestunNatType( StunAddress4& dest,              bool verbose,             bool* preservePort, // if set, is return for if NAT preservers ports or not             bool* 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 );	   if ( hairpin )    {      *hairpin = false;   }	   if ( port == 0 )   {      port = randomPort();   }   UInt32 interfaceIp=0;   if (sAddr)   {      interfaceIp = sAddr->addr;   }   Socket myFd1 = openPort(port,interfaceIp,verbose);   Socket myFd2 = openPort(port+1,interfaceIp,verbose);   if ( ( myFd1 == INVALID_SOCKET) || ( myFd2 == INVALID_SOCKET) )   {        cerr << "Some problem opening port/interface to send on" << endl;       return StunTypeFailure;    }   assert( myFd1 != INVALID_SOCKET );   assert( myFd2 != INVALID_SOCKET );       bool respTestI=false;   bool isNat=true;   StunAddress4 testIchangedAddr;   StunAddress4 testImappedAddr;   bool respTestI2=false;    bool mappedIpSame = true;   StunAddress4 testI2mappedAddr;   StunAddress4 testI2dest=dest;   bool respTestII=false;   bool respTestIII=false;   bool respTestHairpin=false;	   memset(&testImappedAddr,0,sizeof(testImappedAddr));	   StunAtrString username;   StunAtrString password;	   username.sizeValue = 0;   password.sizeValue = 0;	#ifdef USE_TLS    stunGetUserNameAndPassword( dest, username, password );#endif	   //stunSendTest( myFd1, dest, username, password, 1, verbose );   int count=0;   while ( count < 7 )   {      struct timeval tv;      fd_set fdSet; #ifdef WIN32      unsigned int fdSetSize;#else      int fdSetSize;#endif      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;

⌨️ 快捷键说明

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