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

📄 client.cxx

📁 STUN 协议源程序,已在LINUX上编译通过
💻 CXX
字号:
#include <cassert>#include <cstring>#include <iostream>#include <cstdlib>   #ifdef WIN32#include <time.h>#else#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <netinet/in.h>#include <errno.h>#endif#include "udp.h"#include "stun.h"using namespace std;voidusage(){   cerr << "Usage:" << endl	<< "    ./client stunServerHostname [testNumber] [-v] [-p srcPort] [-i nicAddr1] [-i nicAddr2] [-i nicAddr3]" << endl	<< "For example, if the STUN server was larry.gloo.net, you could do:" << endl	<< "    ./client larry.gloo.net" << endl	<< "The testNumber is just used for special tests." << endl	<< " test 1 runs test 1 from the RFC. For example:" << endl	<< "    ./client larry.gloo.net 0" << endl << endl        << endl;}#define MAX_NIC 3intmain(int argc, char* argv[]){   assert( sizeof(UInt8 ) == 1 );   assert( sizeof(UInt16) == 2 );   assert( sizeof(UInt32) == 4 );       initNetwork();       cout << "STUN client version " << STUN_VERSION << endl;      int testNum = 0;   bool verbose = false;	   StunAddress4 stunServerAddr;   stunServerAddr.addr=0;   int srcPort=0;   StunAddress4 sAddr[MAX_NIC];   int retval[MAX_NIC];   int numNic=0;   for ( int i=0; i<MAX_NIC; i++ )   {      sAddr[i].addr=0;       sAddr[i].port=0;       retval[i]=0;   }      for ( int arg = 1; arg<argc; arg++ )   {      if ( !strcmp( argv[arg] , "-v" ) )      {         verbose = true;      }      else if ( !strcmp( argv[arg] , "-i" ) )      {         arg++;         if ( argc <= arg )          {            usage();            exit(-1);         }         if ( numNic >= MAX_NIC )         {              cerr << "Can not have more than "<<  MAX_NIC <<" -i options" << endl;            usage();            exit(-1);         }                  stunParseServerName(argv[arg], sAddr[numNic++]);      }      else if ( !strcmp( argv[arg] , "-p" ) )      {         arg++;         if ( argc <= arg )          {            usage();            exit(-1);         }         srcPort = strtol( argv[arg], NULL, 10);      }      else          {        char* ptr;        int t =  strtol( argv[arg], &ptr, 10 );        if ( *ptr == 0 )        {            // conversion worked           testNum = t;           cout << "running test number " << testNum  << endl;         }        else        {           bool ret = stunParseServerName( argv[arg], stunServerAddr);           if ( ret != true )           {              cerr << argv[arg] << " is not a valid host name " << endl;              usage();              exit(-1);           }	}	      }   }   if ( srcPort == 0 )   {      srcPort = stunRandomPort();   }      if ( numNic == 0 )   {      // use default       numNic = 1;   }      for ( int nic=0; nic<numNic; nic++ )   {      sAddr[nic].port=srcPort;      if ( stunServerAddr.addr == 0 )      {         usage();         exit(-1);      }         if (testNum==0)      {         bool presPort=false;         bool hairpin=false;		         NatType stype = stunNatType( stunServerAddr, verbose, &presPort, &hairpin,                                       srcPort, &sAddr[nic]);		         if ( nic == 0 )         {            cout << "Primary: ";         }         else         {            cout << "Secondary: ";         }                  switch (stype)         {            case StunTypeFailure:               cout << "Some stun error detetecting NAT type";	       retval[nic] = -1;               exit(-1);               break;            case StunTypeUnknown:               cout << "Some unknown type error detetecting NAT type";	       retval[nic] = 0xEE;               break;            case StunTypeOpen:               cout << "Open";	       retval[nic] = 0x00;                break;            case StunTypeIndependentFilter:               cout << "Independent Mapping, Independent Filter";               if ( presPort ) cout << ", preserves ports"; else cout << ", random port";               if ( hairpin  ) cout << ", will hairpin"; else cout << ", no hairpin";               retval[nic] = 0x02;               break;            case StunTypeDependentFilter:               cout << "Independedt Mapping, Address Dependendent Filter";               if ( presPort ) cout << ", preserves ports"; else cout << ", random port";               if ( hairpin  ) cout << ", will hairpin"; else cout << ", no hairpin";               retval[nic] = 0x04;               break;            case StunTypePortDependedFilter:               cout << "Indepndent Mapping, Port Dependent Filter";               if ( presPort ) cout << ", preserves ports"; else cout << ", random port";               if ( hairpin  ) cout << ", will hairpin"; else cout << ", no hairpin";               retval[nic] = 0x06;               break;            case StunTypeDependentMapping:               cout << "Dependent Mapping";               if ( presPort ) cout << ", preserves ports"; else cout << ", random port";               if ( hairpin  ) cout << ", will hairpin"; else cout << ", no hairpin";               retval[nic] = 0x08;               break;            case StunTypeFirewall:               cout << "Firewall";               retval[nic] = 0x0A;               break;            case StunTypeBlocked:               cout << "Blocked or could not reach STUN server";               retval[nic] = 0x0C;               break;            default:               cout << stype;               cout << "Unkown NAT type";               retval[nic] = 0x0E;  // Unknown NAT type               break;         }         cout << "\t"; cout.flush();                  if (!hairpin)         {             retval[nic] |= 0x10;         }                if (presPort)         {             retval[nic] |= 0x01;         }      }      else if (testNum==100)      {         Socket myFd = openPort(srcPort,sAddr[nic].addr,verbose);               StunMessage req;         memset(&req, 0, sizeof(StunMessage));               StunAtrString username;         StunAtrString password;         username.sizeValue = 0;         password.sizeValue = 0;               stunBuildReqSimple( &req, username,                              false , false ,                              0x0c );               char buf[STUN_MAX_MESSAGE_SIZE];         int len = STUN_MAX_MESSAGE_SIZE;               len = stunEncodeMessage( req, buf, len, password,verbose );               if ( verbose )         {            cout << "About to send msg of len " << len                  << " to " << stunServerAddr << endl;         }               while (1)         {            for ( int i=0; i<100; i++ )            {               sendMessage( myFd,                            buf, len,                             stunServerAddr.addr,                             stunServerAddr.port,verbose );            }#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         }      }      else if (testNum==-2)      {         const int numPort = 5;         int fd[numPort];         StunAddress4 mappedAddr;                  for( int i=0; i<numPort; i++ )         {            fd[i] = stunOpenSocket( stunServerAddr, &mappedAddr,                                    (srcPort==0)?0:(srcPort+i), &sAddr[nic],                                    verbose );            cout << "Got port at " << mappedAddr.port << endl;         }                   for( int i=0; i<numPort; i++ )         {            closesocket(fd[i]);         }      }      else if (testNum==-1)      {         int fd3,fd4;         StunAddress4 mappedAddr;                  bool ok = stunOpenSocketPair(stunServerAddr,                                      &mappedAddr,                                      &fd3,                                      &fd4,                                      srcPort,                                       &sAddr[nic],                                      verbose);         if ( ok )         {            closesocket(fd3);            closesocket(fd4);            cout << "Got port pair at " << mappedAddr.port << endl;         }         else         {            cerr << "Opened a stun socket pair FAILED" << endl;         }      }      else      {         stunTest( stunServerAddr,testNum,verbose,&(sAddr[nic]) );      }   } // end of for loop    cout << endl;      UInt32 ret=0;   for ( int i=numNic-1; i>=0; i-- )   {      if ( retval[i] == -1 )      {         ret = 0xFFFFFFFF;         break;      }      ret = ret << 8;      ret = ret | ( retval[i] & 0xFF );   }      cout << "Return value is " << hex << "0x";   cout.fill('0');   cout.width(6);   cout << ret << dec << endl;   cout.fill(' ');      return ret;}/* ==================================================================== * 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 more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * */// Local Variables:// mode:c++// c-file-style:"ellemtel"// c-file-offsets:((case-label . +))// indent-tabs-mode:nil// End:

⌨️ 快捷键说明

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