1 |
sgodin |
7321 |
#include <iostream> |
2 |
dpocock |
9880 |
#include <csignal> |
3 |
sgodin |
7321 |
#include <string> |
4 |
|
|
#include <asio.hpp> |
5 |
|
|
#include <boost/bind.hpp> |
6 |
|
|
#include <boost/function.hpp> |
7 |
|
|
#include <boost/lexical_cast.hpp> |
8 |
|
|
#include <rutil/Data.hxx> |
9 |
dpocock |
9542 |
#include "reTurnServer.hxx" |
10 |
sgodin |
7423 |
#include "TcpServer.hxx" |
11 |
|
|
#include "TlsServer.hxx" |
12 |
sgodin |
7321 |
#include "UdpServer.hxx" |
13 |
sgodin |
8408 |
#include "ReTurnConfig.hxx" |
14 |
sgodin |
7321 |
#include "RequestHandler.hxx" |
15 |
|
|
#include "TurnManager.hxx" |
16 |
sgodin |
7476 |
#include <rutil/WinLeakCheck.hxx> |
17 |
sgodin |
7501 |
#include <rutil/Log.hxx> |
18 |
|
|
#include <rutil/Logger.hxx> |
19 |
|
|
#include "ReTurnSubsystem.hxx" |
20 |
sgodin |
7321 |
|
21 |
sgodin |
7501 |
#define RESIPROCATE_SUBSYSTEM ReTurnSubsystem::RETURN |
22 |
|
|
|
23 |
sgodin |
7321 |
#if defined(_WIN32) |
24 |
|
|
|
25 |
|
|
boost::function0<void> console_ctrl_function; |
26 |
|
|
|
27 |
|
|
BOOL WINAPI console_ctrl_handler(DWORD ctrl_type) |
28 |
|
|
{ |
29 |
|
|
switch (ctrl_type) |
30 |
|
|
{ |
31 |
|
|
case CTRL_C_EVENT: |
32 |
|
|
case CTRL_BREAK_EVENT: |
33 |
|
|
case CTRL_CLOSE_EVENT: |
34 |
|
|
case CTRL_SHUTDOWN_EVENT: |
35 |
|
|
console_ctrl_function(); |
36 |
|
|
return TRUE; |
37 |
|
|
default: |
38 |
|
|
return FALSE; |
39 |
|
|
} |
40 |
|
|
} |
41 |
sgodin |
7322 |
#endif // defined(_WIN32) |
42 |
sgodin |
7321 |
|
43 |
|
|
int main(int argc, char* argv[]) |
44 |
|
|
{ |
45 |
dpocock |
9542 |
reTurn::ReTurnServerProcess proc; |
46 |
sgodin |
9633 |
return proc.main(argc, argv); |
47 |
dpocock |
9542 |
} |
48 |
|
|
|
49 |
|
|
reTurn::ReTurnServerProcess::ReTurnServerProcess() |
50 |
|
|
{ |
51 |
|
|
} |
52 |
|
|
|
53 |
|
|
reTurn::ReTurnServerProcess::~ReTurnServerProcess() |
54 |
|
|
{ |
55 |
|
|
} |
56 |
|
|
|
57 |
|
|
int |
58 |
|
|
reTurn::ReTurnServerProcess::main(int argc, char* argv[]) |
59 |
|
|
{ |
60 |
jmatthewsr |
8134 |
#if defined(WIN32) && defined(_DEBUG) && defined(LEAK_CHECK) |
61 |
sgodin |
8383 |
resip::FindMemoryLeaks fml; |
62 |
sgodin |
7476 |
#endif |
63 |
|
|
|
64 |
dpocock |
9329 |
resip::Data defaultConfig("reTurnServer.config"); |
65 |
sgodin |
9858 |
reTurn::ReTurnConfig reTurnConfig; |
66 |
|
|
try |
67 |
|
|
{ |
68 |
|
|
reTurnConfig.parseConfig(argc, argv, defaultConfig); |
69 |
|
|
} |
70 |
|
|
catch(std::exception& e) |
71 |
|
|
{ |
72 |
|
|
ErrLog(<< "Exception parsing configuration: " << e.what()); |
73 |
|
|
exit(-1); |
74 |
|
|
} |
75 |
sgodin |
8408 |
|
76 |
dpocock |
9544 |
setPidFile(reTurnConfig.mPidFile); |
77 |
dpocock |
9362 |
// Daemonize if necessary |
78 |
|
|
if(reTurnConfig.mDaemonize) |
79 |
sgodin |
9858 |
{ |
80 |
dpocock |
9542 |
daemonize(); |
81 |
sgodin |
9858 |
} |
82 |
dpocock |
9362 |
|
83 |
sgodin |
8383 |
try |
84 |
|
|
{ |
85 |
sgodin |
8408 |
// Initialize Logging |
86 |
|
|
resip::Log::initialize(reTurnConfig.mLoggingType, reTurnConfig.mLoggingLevel, "reTurnServer", reTurnConfig.mLoggingFilename.c_str()); |
87 |
|
|
resip::GenericLogImpl::MaxLineCount = reTurnConfig.mLoggingFileMaxLineCount; |
88 |
sgodin |
7321 |
|
89 |
sgodin |
8383 |
// Initialize server. |
90 |
sgodin |
8408 |
asio::io_service ioService; // The one and only ioService for the stunServer |
91 |
|
|
reTurn::TurnManager turnManager(ioService, reTurnConfig); // The one and only Turn Manager |
92 |
sgodin |
7321 |
|
93 |
sgodin |
8383 |
boost::shared_ptr<reTurn::UdpServer> udpTurnServer; // also a1p1StunUdpServer |
94 |
|
|
boost::shared_ptr<reTurn::TcpServer> tcpTurnServer; |
95 |
|
|
boost::shared_ptr<reTurn::TlsServer> tlsTurnServer; |
96 |
|
|
boost::shared_ptr<reTurn::UdpServer> a1p2StunUdpServer; |
97 |
|
|
boost::shared_ptr<reTurn::UdpServer> a2p1StunUdpServer; |
98 |
|
|
boost::shared_ptr<reTurn::UdpServer> a2p2StunUdpServer; |
99 |
sgodin |
7365 |
|
100 |
Dpocock |
10468 |
#ifdef USE_IPV6 |
101 |
|
|
boost::shared_ptr<reTurn::UdpServer> udpV6TurnServer; |
102 |
|
|
boost::shared_ptr<reTurn::TcpServer> tcpV6TurnServer; |
103 |
|
|
boost::shared_ptr<reTurn::TlsServer> tlsV6TurnServer; |
104 |
|
|
#endif |
105 |
|
|
|
106 |
sgodin |
8383 |
// The one and only RequestHandler - if altStunPort is non-zero, then assume RFC3489 support is enabled and pass settings to request handler |
107 |
|
|
reTurn::RequestHandler requestHandler(turnManager, |
108 |
sgodin |
8408 |
reTurnConfig.mAltStunPort != 0 ? &reTurnConfig.mTurnAddress : 0, |
109 |
|
|
reTurnConfig.mAltStunPort != 0 ? &reTurnConfig.mTurnPort : 0, |
110 |
|
|
reTurnConfig.mAltStunPort != 0 ? &reTurnConfig.mAltStunAddress : 0, |
111 |
|
|
reTurnConfig.mAltStunPort != 0 ? &reTurnConfig.mAltStunPort : 0); |
112 |
sgodin |
7348 |
|
113 |
sgodin |
8408 |
udpTurnServer.reset(new reTurn::UdpServer(ioService, requestHandler, reTurnConfig.mTurnAddress, reTurnConfig.mTurnPort)); |
114 |
|
|
tcpTurnServer.reset(new reTurn::TcpServer(ioService, requestHandler, reTurnConfig.mTurnAddress, reTurnConfig.mTurnPort)); |
115 |
|
|
tlsTurnServer.reset(new reTurn::TlsServer(ioService, requestHandler, reTurnConfig.mTurnAddress, reTurnConfig.mTlsTurnPort)); |
116 |
sgodin |
7348 |
|
117 |
Dpocock |
10468 |
#ifdef USE_IPV6 |
118 |
|
|
udpV6TurnServer.reset(new reTurn::UdpServer(ioService, requestHandler, reTurnConfig.mTurnV6Address, reTurnConfig.mTurnPort)); |
119 |
|
|
tcpV6TurnServer.reset(new reTurn::TcpServer(ioService, requestHandler, reTurnConfig.mTurnV6Address, reTurnConfig.mTurnPort)); |
120 |
|
|
tlsV6TurnServer.reset(new reTurn::TlsServer(ioService, requestHandler, reTurnConfig.mTurnV6Address, reTurnConfig.mTlsTurnPort)); |
121 |
|
|
#endif |
122 |
|
|
|
123 |
sgodin |
8408 |
if(reTurnConfig.mAltStunPort != 0) // if alt stun port is non-zero, then RFC3489 support is enabled |
124 |
sgodin |
8383 |
{ |
125 |
sgodin |
8408 |
a1p2StunUdpServer.reset(new reTurn::UdpServer(ioService, requestHandler, reTurnConfig.mTurnAddress, reTurnConfig.mAltStunPort)); |
126 |
|
|
a2p1StunUdpServer.reset(new reTurn::UdpServer(ioService, requestHandler, reTurnConfig.mAltStunAddress, reTurnConfig.mTurnPort)); |
127 |
|
|
a2p2StunUdpServer.reset(new reTurn::UdpServer(ioService, requestHandler, reTurnConfig.mAltStunAddress, reTurnConfig.mAltStunPort)); |
128 |
sgodin |
8383 |
udpTurnServer->setAlternateUdpServers(a1p2StunUdpServer.get(), a2p1StunUdpServer.get(), a2p2StunUdpServer.get()); |
129 |
|
|
a1p2StunUdpServer->setAlternateUdpServers(udpTurnServer.get(), a2p2StunUdpServer.get(), a2p1StunUdpServer.get()); |
130 |
|
|
a2p1StunUdpServer->setAlternateUdpServers(a2p2StunUdpServer.get(), udpTurnServer.get(), a1p2StunUdpServer.get()); |
131 |
|
|
a2p2StunUdpServer->setAlternateUdpServers(a2p1StunUdpServer.get(), a1p2StunUdpServer.get(), udpTurnServer.get()); |
132 |
|
|
a1p2StunUdpServer->start(); |
133 |
|
|
a2p1StunUdpServer->start(); |
134 |
|
|
a2p2StunUdpServer->start(); |
135 |
|
|
} |
136 |
sgodin |
7754 |
|
137 |
sgodin |
8383 |
udpTurnServer->start(); |
138 |
|
|
tcpTurnServer->start(); |
139 |
|
|
tlsTurnServer->start(); |
140 |
|
|
|
141 |
Dpocock |
10468 |
#ifdef USE_IPV6 |
142 |
|
|
udpV6TurnServer->start(); |
143 |
|
|
tcpV6TurnServer->start(); |
144 |
|
|
tlsV6TurnServer->start(); |
145 |
|
|
#endif |
146 |
|
|
|
147 |
dpocock |
10086 |
// Drop privileges (can do this now that sockets are bound) |
148 |
|
|
if(!reTurnConfig.mRunAsUser.empty()) |
149 |
|
|
{ |
150 |
|
|
InfoLog( << "Trying to drop privileges, configured uid = " << reTurnConfig.mRunAsUser << " gid = " << reTurnConfig.mRunAsGroup); |
151 |
|
|
dropPrivileges(reTurnConfig.mRunAsUser, reTurnConfig.mRunAsGroup); |
152 |
|
|
} |
153 |
|
|
|
154 |
sgodin |
7322 |
#ifdef _WIN32 |
155 |
sgodin |
8383 |
// Set console control handler to allow server to be stopped. |
156 |
|
|
console_ctrl_function = boost::bind(&asio::io_service::stop, &ioService); |
157 |
|
|
SetConsoleCtrlHandler(console_ctrl_handler, TRUE); |
158 |
sgodin |
7322 |
#else |
159 |
sgodin |
8383 |
// Block all signals for background thread. |
160 |
|
|
sigset_t new_mask; |
161 |
|
|
sigfillset(&new_mask); |
162 |
|
|
sigset_t old_mask; |
163 |
|
|
pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); |
164 |
sgodin |
7322 |
#endif |
165 |
sgodin |
7321 |
|
166 |
sgodin |
8383 |
// Run the ioService until stopped. |
167 |
|
|
// Create a pool of threads to run all of the io_services. |
168 |
|
|
boost::shared_ptr<asio::thread> thread(new asio::thread( |
169 |
|
|
boost::bind(&asio::io_service::run, &ioService))); |
170 |
sgodin |
7321 |
|
171 |
sgodin |
7322 |
#ifndef _WIN32 |
172 |
sgodin |
8383 |
// Restore previous signals. |
173 |
|
|
pthread_sigmask(SIG_SETMASK, &old_mask, 0); |
174 |
sgodin |
7322 |
|
175 |
sgodin |
8383 |
// Wait for signal indicating time to shut down. |
176 |
|
|
sigset_t wait_mask; |
177 |
|
|
sigemptyset(&wait_mask); |
178 |
|
|
sigaddset(&wait_mask, SIGINT); |
179 |
|
|
sigaddset(&wait_mask, SIGQUIT); |
180 |
|
|
sigaddset(&wait_mask, SIGTERM); |
181 |
|
|
pthread_sigmask(SIG_BLOCK, &wait_mask, 0); |
182 |
|
|
int sig = 0; |
183 |
|
|
sigwait(&wait_mask, &sig); |
184 |
|
|
ioService.stop(); |
185 |
sgodin |
7322 |
#endif |
186 |
|
|
|
187 |
sgodin |
8383 |
// Wait for thread to exit |
188 |
|
|
thread->join(); |
189 |
|
|
} |
190 |
|
|
catch (std::exception& e) |
191 |
|
|
{ |
192 |
|
|
ErrLog(<< "exception: " << e.what()); |
193 |
|
|
} |
194 |
sgodin |
7321 |
|
195 |
sgodin |
8383 |
return 0; |
196 |
sgodin |
7321 |
} |
197 |
|
|
|
198 |
|
|
|
199 |
sgodin |
7366 |
/* ==================================================================== |
200 |
|
|
|
201 |
sgodin |
8367 |
Copyright (c) 2007-2008, Plantronics, Inc. |
202 |
|
|
All rights reserved. |
203 |
sgodin |
7366 |
|
204 |
|
|
Redistribution and use in source and binary forms, with or without |
205 |
sgodin |
8367 |
modification, are permitted provided that the following conditions are |
206 |
|
|
met: |
207 |
|
|
|
208 |
|
|
1. Redistributions of source code must retain the above copyright |
209 |
|
|
notice, this list of conditions and the following disclaimer. |
210 |
|
|
|
211 |
sgodin |
7366 |
2. Redistributions in binary form must reproduce the above copyright |
212 |
sgodin |
8367 |
notice, this list of conditions and the following disclaimer in the |
213 |
|
|
documentation and/or other materials provided with the distribution. |
214 |
sgodin |
7366 |
|
215 |
sgodin |
8367 |
3. Neither the name of Plantronics nor the names of its contributors |
216 |
|
|
may be used to endorse or promote products derived from this |
217 |
|
|
software without specific prior written permission. |
218 |
|
|
|
219 |
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
220 |
|
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
221 |
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
222 |
|
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
223 |
|
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
224 |
|
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
225 |
|
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
226 |
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
227 |
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
228 |
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
229 |
|
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
230 |
|
|
|
231 |
sgodin |
7366 |
==================================================================== */ |