Commit 9c0e8a94 authored by Spencer Lambert's avatar Spencer Lambert Committed by John Selbie

Allow other processes to bind to the STUN UDP port. (#20)

* allow multiple port binds for UDP

* adding --reuseaddr command line switch for setting the SO_REUSEADDR option

* initializing fReuseAddr and modifying help page
parent 137c2f09
...@@ -506,7 +506,7 @@ HRESULT UdpClientLoop(StunClientLogicConfig& config, const ClientSocketConfig& s ...@@ -506,7 +506,7 @@ HRESULT UdpClientLoop(StunClientLogicConfig& config, const ClientSocketConfig& s
Chk(hr); Chk(hr);
} }
hr = stunSocket.UDPInit(socketconfig.addrLocal, RolePP); hr = stunSocket.UDPInit(socketconfig.addrLocal, RolePP, false);
if (FAILED(hr)) if (FAILED(hr))
{ {
Logging::LogMsg(LL_ALWAYS, "Unable to create local socket: (error = x%x)", hr); Logging::LogMsg(LL_ALWAYS, "Unable to create local socket: (error = x%x)", hr);
......
...@@ -319,9 +319,9 @@ Cleanup: ...@@ -319,9 +319,9 @@ Cleanup:
HRESULT CStunSocket::UDPInit(const CSocketAddress& local, SocketRole role) HRESULT CStunSocket::UDPInit(const CSocketAddress& local, SocketRole role, bool fSetReuseFlag)
{ {
return InitCommon(SOCK_DGRAM, local, role, false); return InitCommon(SOCK_DGRAM, local, role, fSetReuseFlag);
} }
HRESULT CStunSocket::TCPInit(const CSocketAddress& local, SocketRole role, bool fSetReuseFlag) HRESULT CStunSocket::TCPInit(const CSocketAddress& local, SocketRole role, bool fSetReuseFlag)
......
...@@ -65,7 +65,7 @@ public: ...@@ -65,7 +65,7 @@ public:
void UpdateAddresses(); void UpdateAddresses();
HRESULT UDPInit(const CSocketAddress& local, SocketRole role); HRESULT UDPInit(const CSocketAddress& local, SocketRole role, bool fSetReuseFlag);
HRESULT TCPInit(const CSocketAddress& local, SocketRole role, bool fSetReuseFlag); HRESULT TCPInit(const CSocketAddress& local, SocketRole role, bool fSetReuseFlag);
}; };
......
...@@ -221,7 +221,18 @@ the same process (each in a separate thread). ...@@ -221,7 +221,18 @@ the same process (each in a separate thread).
The fields of each configuration node are named identical to the The fields of each configuration node are named identical to the
corresponding command line parameters (with the leading dashes removed). corresponding command line parameters (with the leading dashes removed).
An example stun.conf configuration file is shipped in the "testcode" An example stun.conf configuration file is shipped in the "testcode"
folder of the source package ____ folder of the source package
.PP
* * * * *
.PP
\f[B]\-\-reuseaddr\f[]
.PP
The \-\-reuseaddr switch allows the STUN server port to be shared with
other processes.
This is useful for scenarios where another process needs to send from
the STUN server port.
.PP
* * * * *
.PP .PP
\f[B]\-\-help\f[] \f[B]\-\-help\f[]
.PP .PP
......
...@@ -198,6 +198,12 @@ configuration file is shipped in the "testcode" folder of the source package ...@@ -198,6 +198,12 @@ configuration file is shipped in the "testcode" folder of the source package
____ ____
**--reuseaddr**
The --reuseaddr switch allows the STUN server port to be shared with other processes. This is useful for scenarios where another process needs to send from the STUN server port.
____
**--help** **--help**
Prints this help page Prints this help page
......
This diff is collapsed.
...@@ -128,6 +128,7 @@ struct StartupArgs ...@@ -128,6 +128,7 @@ struct StartupArgs
std::string strMaxConnections; std::string strMaxConnections;
std::string strDosProtect; std::string strDosProtect;
std::string strConfigFile; std::string strConfigFile;
std::string strReuseAddr;
}; };
...@@ -149,6 +150,7 @@ void DumpStartupArgs(StartupArgs& args) ...@@ -149,6 +150,7 @@ void DumpStartupArgs(StartupArgs& args)
PRINTARG(strVerbosity); PRINTARG(strVerbosity);
PRINTARG(strMaxConnections); PRINTARG(strMaxConnections);
PRINTARG(strDosProtect); PRINTARG(strDosProtect);
PRINTARG(strReuseAddr);
Logging::LogMsg(LL_DEBUG, "--------------------------\n"); Logging::LogMsg(LL_DEBUG, "--------------------------\n");
} }
...@@ -508,6 +510,9 @@ HRESULT BuildServerConfigurationFromArgs(StartupArgs& argsIn, CStunServerConfig* ...@@ -508,6 +510,9 @@ HRESULT BuildServerConfigurationFromArgs(StartupArgs& argsIn, CStunServerConfig*
// ---- DDOS PROTECTION SWITCH ------------------------------------------- // ---- DDOS PROTECTION SWITCH -------------------------------------------
config.fEnableDosProtection = (argsIn.strDosProtect.length() > 0); config.fEnableDosProtection = (argsIn.strDosProtect.length() > 0);
// ---- REUSE ADDRESS SWITCH -------------------------------------------
config.fReuseAddr = (argsIn.strReuseAddr.length() > 0);
*pConfigOut = config; *pConfigOut = config;
hr = S_OK; hr = S_OK;
...@@ -536,6 +541,7 @@ HRESULT ParseCommandLineArgs(int argc, char** argv, int startindex, StartupArgs* ...@@ -536,6 +541,7 @@ HRESULT ParseCommandLineArgs(int argc, char** argv, int startindex, StartupArgs*
cmdline.AddOption("verbosity", required_argument, &pStartupArgs->strVerbosity); cmdline.AddOption("verbosity", required_argument, &pStartupArgs->strVerbosity);
cmdline.AddOption("ddp", no_argument, &pStartupArgs->strDosProtect); cmdline.AddOption("ddp", no_argument, &pStartupArgs->strDosProtect);
cmdline.AddOption("configfile", required_argument, &pStartupArgs->strConfigFile); cmdline.AddOption("configfile", required_argument, &pStartupArgs->strConfigFile);
cmdline.AddOption("reuseaddr", no_argument, &pStartupArgs->strReuseAddr);
cmdline.ParseCommandLine(argc, argv, startindex, &fError); cmdline.ParseCommandLine(argc, argv, startindex, &fError);
...@@ -591,6 +597,7 @@ HRESULT LoadConfigsFromFile(const std::string& filename, std::vector<StartupArgs ...@@ -591,6 +597,7 @@ HRESULT LoadConfigsFromFile(const std::string& filename, std::vector<StartupArgs
args.strProtocol = child.get("protocol", ""); args.strProtocol = child.get("protocol", "");
args.strMaxConnections = child.get("maxconn", ""); args.strMaxConnections = child.get("maxconn", "");
args.strDosProtect = child.get("ddp", ""); args.strDosProtect = child.get("ddp", "");
args.strReuseAddr = child.get("reuseaddr", "");
configurations.push_back(args); configurations.push_back(args);
} }
......
...@@ -32,7 +32,8 @@ fHasAA(false), ...@@ -32,7 +32,8 @@ fHasAA(false),
fMultiThreadedMode(false), fMultiThreadedMode(false),
fTCP(false), fTCP(false),
nMaxConnections(0), // zero means default nMaxConnections(0), // zero means default
fEnableDosProtection(false) fEnableDosProtection(false),
fReuseAddr(false)
{ {
; ;
} }
...@@ -50,13 +51,13 @@ CStunServer::~CStunServer() ...@@ -50,13 +51,13 @@ CStunServer::~CStunServer()
Shutdown(); Shutdown();
} }
HRESULT CStunServer::AddSocket(TransportAddressSet* pTSA, SocketRole role, const CSocketAddress& addrListen, const CSocketAddress& addrAdvertise) HRESULT CStunServer::AddSocket(TransportAddressSet* pTSA, SocketRole role, const CSocketAddress& addrListen, const CSocketAddress& addrAdvertise, bool fSetReuseFlag)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
ASSERT(IsValidSocketRole(role)); ASSERT(IsValidSocketRole(role));
Chk(_arrSockets[role].UDPInit(addrListen, role)); Chk(_arrSockets[role].UDPInit(addrListen, role, fSetReuseFlag));
ChkA(_arrSockets[role].EnablePktInfoOption(true)); ChkA(_arrSockets[role].EnablePktInfoOption(true));
...@@ -110,25 +111,25 @@ HRESULT CStunServer::Initialize(const CStunServerConfig& config) ...@@ -110,25 +111,25 @@ HRESULT CStunServer::Initialize(const CStunServerConfig& config)
// Create the sockets and initialize the TSA thing // Create the sockets and initialize the TSA thing
if (config.fHasPP) if (config.fHasPP)
{ {
Chk(AddSocket(&tsa, RolePP, config.addrPP, config.addrPrimaryAdvertised)); Chk(AddSocket(&tsa, RolePP, config.addrPP, config.addrPrimaryAdvertised, config.fReuseAddr));
socketcount++; socketcount++;
} }
if (config.fHasPA) if (config.fHasPA)
{ {
Chk(AddSocket(&tsa, RolePA, config.addrPA, config.addrPrimaryAdvertised)); Chk(AddSocket(&tsa, RolePA, config.addrPA, config.addrPrimaryAdvertised, config.fReuseAddr));
socketcount++; socketcount++;
} }
if (config.fHasAP) if (config.fHasAP)
{ {
Chk(AddSocket(&tsa, RoleAP, config.addrAP, config.addrAlternateAdvertised)); Chk(AddSocket(&tsa, RoleAP, config.addrAP, config.addrAlternateAdvertised, config.fReuseAddr));
socketcount++; socketcount++;
} }
if (config.fHasAA) if (config.fHasAA)
{ {
Chk(AddSocket(&tsa, RoleAA, config.addrAA, config.addrAlternateAdvertised)); Chk(AddSocket(&tsa, RoleAA, config.addrAA, config.addrAlternateAdvertised, config.fReuseAddr));
socketcount++; socketcount++;
} }
......
...@@ -50,6 +50,8 @@ public: ...@@ -50,6 +50,8 @@ public:
bool fEnableDosProtection; // enable denial of service protection bool fEnableDosProtection; // enable denial of service protection
bool fReuseAddr; // if true, the socket option SO_REUSEADDR will be set
CStunServerConfig(); CStunServerConfig();
}; };
...@@ -71,7 +73,7 @@ private: ...@@ -71,7 +73,7 @@ private:
CRefCountedPtr<IStunAuth> _spAuth; CRefCountedPtr<IStunAuth> _spAuth;
HRESULT AddSocket(TransportAddressSet* pTSA, SocketRole role, const CSocketAddress& addrListen, const CSocketAddress& addrAdvertise); HRESULT AddSocket(TransportAddressSet* pTSA, SocketRole role, const CSocketAddress& addrListen, const CSocketAddress& addrAdvertise, bool fSetReuseFlag);
public: public:
......
...@@ -70,9 +70,9 @@ HRESULT CTestRecvFromEx::DoTest(bool fIPV6) ...@@ -70,9 +70,9 @@ HRESULT CTestRecvFromEx::DoTest(bool fIPV6)
// create two sockets listening on INADDR_ANY. One for sending and one for receiving // create two sockets listening on INADDR_ANY. One for sending and one for receiving
ChkA(socketSend.UDPInit(addrAny, RolePP)); ChkA(socketSend.UDPInit(addrAny, RolePP, false));
ChkA(socketRecv.UDPInit(addrAny, RolePP)); ChkA(socketRecv.UDPInit(addrAny, RolePP, false));
socketRecv.EnablePktInfoOption(true); socketRecv.EnablePktInfoOption(true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment