reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
TurnLoadGenClient.cxx
Go to the documentation of this file.
1#if defined(HAVE_CONFIG_H)
2#include "config.h"
3#endif
4
5#ifdef WIN32
6#pragma warning(disable : 4267)
7#endif
8
9#include <iostream>
10#include <string>
11#include <asio.hpp>
12#ifdef USE_SSL
13#include <asio/ssl.hpp>
14#endif
15#include <rutil/ThreadIf.hxx>
16
17#include "../../StunTuple.hxx"
18#include "../../StunMessage.hxx"
19#include "../TurnUdpSocket.hxx"
20#include "../TurnAsyncTcpSocket.hxx"
21#include "../TurnAsyncTlsSocket.hxx"
22#include "../TurnAsyncUdpSocket.hxx"
23#include "../TurnAsyncSocketHandler.hxx"
24#include "../UdpEchoServer.hxx"
26#include <rutil/Timer.hxx>
27#include <rutil/Random.hxx>
28#include <rutil/Logger.hxx>
29#include <rutil/DnsUtil.hxx>
31
32#ifdef BOOST_ASIO_HAS_STD_CHRONO
33using namespace std::chrono;
34#else
35#include <chrono>
36using namespace std::chrono;
37#endif
38
39using namespace reTurn;
40using namespace std;
41using namespace resip;
42
43#define RESIPROCATE_SUBSYSTEM resip::Subsystem::TEST
44
45void sleepMS(unsigned int ms)
46{
47#ifdef WIN32
48 Sleep(ms);
49#else
50 usleep(ms*1000);
51#endif
52}
53
55
57{
58 void printHelpText(int argc, char** argv) override
59 {
60 cout << "Command line format: " << endl;
61 cout << " TurnLoadGenClient [config_filename][-{setting} = {value}] ...." << endl;
62 cout << " First argument is the configuration filename - it is optional and is never proceeded with a - or /." << endl;
63 cout << " Following that config file options can be overridden." << endl;
64 cout << " Note: / can be used instead of - , and : can be used instead of = " << endl;
65 cout << "Example:" << endl;
66 cout << " TurnLoadGenClient myconfig.config -LocalIPAddress=192.168.1.1" << endl;
67 }
68};
69
70int main(int argc, char* argv[])
71{
72#if defined(WIN32) && defined(_DEBUG) && defined(LEAK_CHECK)
73 resip::FindMemoryLeaks fml;
74#endif
75
76 // Parse command line and configuration file
77 TurnLoadGenConfig config;
78 Data defaultConfigFilename("turnloadgenclient.config");
79 try
80 {
81 config.parseConfig(argc, argv, defaultConfigFilename);
82 }
83 catch (BaseException& ex)
84 {
85 std::cerr << "Error parsing configuration: " << ex << std::endl;
86 return 1;
87 }
88
89 Log::initialize(config, "TurnLoadTestGen");
90
91 try
92 {
93 Data localAddress = config.getConfigData("LocalIPAddress", DnsUtil::getLocalIpAddress(), true);
94 Data turnAddress = config.getConfigData("TurnServerIPAddress", localAddress, true);
95 unsigned int turnPort = config.getConfigInt("TurnServerPort", 3478);
96 Data turnProtocol = config.getConfigData("TurnServerProtocol", "UDP", true);
97 unsigned int echoServerPort = config.getConfigInt("RelayPort", 2000);
98
99 InfoLog(<< "Using: " << localAddress << " --" << turnProtocol << "--> " << turnAddress << ":" << turnPort);
100
102
103 Data username = config.getConfigData("TurnServerUsername", "test", false);
104 Data password = config.getConfigData("TurnServerPassword", "pwd", false);
105
106 // Create payload to send
107 int bufferSize = config.getConfigInt("PayloadSizeBytes", 172);
108 if (bufferSize > 1400)
109 {
110 WarningLog(<< "Max PlayloadSizeBytes=" << bufferSize << " exceeds max of 1400, using 1400 instead.");
111 bufferSize = 1400;
112 }
113 char* buffer = new char[bufferSize]; // Contents is not important - leave uninitialized
114 g_Payload = new resip::Data(buffer, bufferSize);
115
116 // Start Echo server - just need one
117 UdpEchoServer udpEchoServer(localAddress, echoServerPort);
118 udpEchoServer.run();
119
120 asio::io_context ioService;
121
122 int numClientsToSimulate = config.getConfigInt("NumClientsToSimulate", 1);
123 std::list<TurnLoadGenAsyncSocketHandler*> mClients;
124 for (int clientNum = 1; clientNum <= numClientsToSimulate; clientNum++)
125 {
126 TurnLoadGenAsyncSocketHandler* client = new TurnLoadGenAsyncSocketHandler(clientNum, ioService, localAddress, turnAddress, turnPort, udpEchoServer.getPort(), config);
127
128 std::shared_ptr<TurnAsyncSocket> turnSocket;
129
130#ifdef USE_SSL
131 asio::ssl::context sslContext(asio::ssl::context::tls_client); // any TLS version reTurn accepts
132 // Setup SSL context
133 sslContext.set_verify_mode(asio::ssl::context::verify_peer);
134 sslContext.load_verify_file(config.getConfigData("TLSRootCertFile", "ca.pem", true).c_str());
135
136 if (isEqualNoCase(turnProtocol, "TLS"))
137 {
138 turnSocket = std::make_shared<TurnAsyncTlsSocket>(ioService, sslContext, false, client, asio::ip::make_address(localAddress.c_str()), 0);
139 }
140 else
141#endif
142 if (isEqualNoCase(turnProtocol, "TCP"))
143 {
144 turnSocket = std::make_shared<TurnAsyncTcpSocket>(ioService, client, asio::ip::make_address(localAddress.c_str()), 0);
145 }
146 else
147 {
148 turnSocket = std::make_shared<TurnAsyncUdpSocket>(ioService, client, asio::ip::make_address(localAddress.c_str()), 0);
149 }
150
151 // Set the username and password
152 if (username.size() > 0 && password.size() > 0)
153 {
154 turnSocket->setUsernameAndPassword(username.c_str(), password.c_str());
155 }
156
157 client->setTurnAsyncSocket(turnSocket);
158
159 mClients.push_back(client);
160 }
161
162 ioService.run();
163
164 udpEchoServer.shutdown();
165 udpEchoServer.join();
166 }
167 catch (const std::exception& e)
168 {
169 std::cerr << "Exception: " << e.what() << "\n";
170 }
171
172 return 0;
173}
174
175
176/* ====================================================================
177
178 Copyright (c) 2023-2026, SIP Spectrum, Inc. http://sipspectrum.com
179 All rights reserved.
180
181 Redistribution and use in source and binary forms, with or without
182 modification, are permitted provided that the following conditions are
183 met:
184
185 1. Redistributions of source code must retain the above copyright
186 notice, this list of conditions and the following disclaimer.
187
188 2. Redistributions in binary form must reproduce the above copyright
189 notice, this list of conditions and the following disclaimer in the
190 documentation and/or other materials provided with the distribution.
191
192 3. Neither the name of Plantronics nor the names of its contributors
193 may be used to endorse or promote products derived from this
194 software without specific prior written permission.
195
196 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
197 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
198 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
199 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
200 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
201 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
202 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
203 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
204 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
205 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
206 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
207
208 ==================================================================== */
websocketpp::client< websocketpp::config::asio_client > client
#define InfoLog(args_)
Definition Logger.hxx:131
#define WarningLog(args_)
Definition Logger.hxx:134
int main(int argc, char *argv[])
resip::Data * g_Payload
void sleepMS(unsigned int ms)
void shutdown() override
The abstract base-class for all exceptions thrown by resip code.
virtual void parseConfig(int argc, char **argv, const resip::Data &defaultConfigFilename)
int getConfigInt(const resip::Data &name, int defaultValue) const
resip::Data getConfigData(const resip::Data &name, const resip::Data &defaultValue, bool useDefaultIfEmpty=false) const
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
const char * c_str() const
Returns a null-terminated string representing.
Definition Data.cxx:1097
size_type size() const noexcept
Returns the number of bytes in this Data.
Definition Data.hxx:599
static Data getLocalIpAddress(const Data &defaultInterface=Data::Empty)
Gets the IP address of "the" local interface.
Definition DnsUtil.cxx:222
static void initialize(Type type, Level level, const Data &appName, const char *logFileName=0, ExternalLogger *externalLogger=0, const Data &syslogFacility="LOG_DAEMON", MessageStructure messageStructure=Unstructured, const Data &instanceName="")
Definition Log.cxx:268
static void initialize()
Definition Random.cxx:125
virtual void run()
Definition ThreadIf.cxx:75
dcm! – add UnusedChecking(_enum) below;
bool isEqualNoCase(const Data &left, const Data &right)
Definition Data.hxx:1116