📄 client.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 + -