1 Star 0 Fork 4

bowangwifi/stund

forked from WolfCS/stund 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
client.cxx 12.57 KB
一键复制 编辑 原始数据 按行查看 历史
#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;
void usage() {
cerr << "Usage:" << endl
<< " ./client stunServerHostname [testNumber] [-v] [-p srcPort] [-t threadNumber] "
"[-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 3
StunAddress4 stunServerAddr;
void *thr_fn(void *arg) {
bool verbose = false;
bool presPort = false;
bool hairpin = false;
int srcPort = stunRandomPort();
stunServerStressTest(stunServerAddr, verbose, &presPort, &hairpin, srcPort, NULL);
return NULL;
}
int main(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;
stunServerAddr.addr = 0;
int srcPort = 0;
StunAddress4 sAddr[MAX_NIC];
int retval[MAX_NIC];
int numNic = 0;
int threadNumber = 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 if (!strcmp(argv[arg], "-t")) {
arg++;
if (argc <= arg) {
usage();
exit(-1);
}
threadNumber = 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;
}
pthread_t *ntids = NULL;
if (threadNumber > 0) {
ntids = new pthread_t[threadNumber];
for (int i = 0; i < threadNumber; ++i) {
int err;
err = pthread_create(&ntids[i], NULL, thr_fn, NULL);
if (err != 0)
cerr << "can't create thread: %s\n" << strerror(err) << endl;
}
}
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 << "Independent Mapping, Address Dependent 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 << "Independent 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);
}
if (threadNumber > 0) {
for (int i = 0; i < threadNumber; ++i) {
pthread_join(ntids[i], NULL);
}
delete [] ntids;
}
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:
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/bowangwfifi/stund.git
git@gitee.com:bowangwfifi/stund.git
bowangwfifi
stund
stund
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385