Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
S
Stunserver
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
Stunserver
Commits
3d23f8f8
Commit
3d23f8f8
authored
Mar 12, 2017
by
jselbie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support for configuration file
parent
2fa4f5de
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
829 additions
and
569 deletions
+829
-569
common/commonincludes.hpp
common/commonincludes.hpp
+2
-0
resources/stunserver.1
resources/stunserver.1
+18
-0
resources/stunserver.md
resources/stunserver.md
+14
-0
resources/stunserver.txtcode
resources/stunserver.txtcode
+597
-522
server/main.cpp
server/main.cpp
+164
-47
testcode/stun.conf
testcode/stun.conf
+34
-0
No files found.
common/commonincludes.hpp
View file @
3d23f8f8
...
...
@@ -51,6 +51,8 @@
#include <boost/shared_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <map>
#include <vector>
...
...
resources/stunserver.1
View file @
3d23f8f8
...
...
@@ -31,6 +31,7 @@ The following options are supported.
\-\-ddp
\-\-primaryadvertised
\-\-altadvertised
\-\-configfile
\-\-help
\f[]
.fi
...
...
@@ -205,6 +206,23 @@ correctly set these parameters for use within Amazon EC2.
.PP
* * * * *
.PP
\f[B]\-\-configfile\f[] FILENAME
.PP
The \-\-configfile switch allows the server to be configured with a JSON
configuration file rather that through command line parameters.
If this switch is specified, most other command line parameters will be
ignored.
(\-\-verbosity is the only one honored).
Instead of configuring the server with command line parameters, the
configuration will be read from file.
Since multiple configurations can be specified, this has the added
advantage of allowing multiple protocols and IP families to run within
the same process (each in a separate thread).
The fields of each configuration node are named identical to the
corresponding command line parameters (with the leading dashes removed).
An example stun.conf configuration file is shipped in the "testcode"
folder of the source package ____
.PP
\f[B]\-\-help\f[]
.PP
Prints this help page
...
...
resources/stunserver.md
View file @
3d23f8f8
...
...
@@ -29,6 +29,7 @@ The following options are supported.
--ddp
--primaryadvertised
--altadvertised
--configfile
--help
Details of each option are as follows.
...
...
@@ -185,6 +186,18 @@ For more details, visit www.stunprotocol.org for details on how to correctly set
____
**--configfile**
FILENAME
The --configfile switch allows the server to be configured with a JSON configuration file rather
that through command line parameters. If this switch is specified, most other command line parameters will be ignored.
(--verbosity is the only one honored). Instead of configuring the server with command line parameters, the configuration
will be read from file. Since multiple configurations can be specified, this has the added advantage of allowing multiple
protocols and IP families to run within the same process (each in a separate thread). The fields of each configuration node
are named identical to the corresponding command line parameters (with the leading dashes removed). An example stun.conf
configuration file is shipped in the "testcode" folder of the source package
____
**--help**
Prints this help page
...
...
@@ -214,6 +227,7 @@ stunserver --mode full --primaryinterface eth0 --altinterface eth1
enumerated by the system. The "ifconfig" or "ipconfig" command will
enumerate available interface names.
# AUTHOR
john selbie (john@selbie.com)
...
...
resources/stunserver.txtcode
View file @
3d23f8f8
This diff is collapsed.
Click to expand it.
server/main.cpp
View file @
3d23f8f8
...
...
@@ -34,6 +34,9 @@
#include "resolvehostname.h"
using
namespace
boost
::
property_tree
;
void
PrintUsage
(
bool
fSummaryUsage
)
{
size_t
width
=
GetConsoleWidth
();
...
...
@@ -120,6 +123,7 @@ struct StartupArgs
std
::
string
strVerbosity
;
std
::
string
strMaxConnections
;
std
::
string
strDosProtect
;
std
::
string
strConfigFile
;
};
...
...
@@ -527,6 +531,7 @@ HRESULT ParseCommandLineArgs(int argc, char** argv, int startindex, StartupArgs*
cmdline
.
AddOption
(
"help"
,
no_argument
,
&
pStartupArgs
->
strHelp
);
cmdline
.
AddOption
(
"verbosity"
,
required_argument
,
&
pStartupArgs
->
strVerbosity
);
cmdline
.
AddOption
(
"ddp"
,
no_argument
,
&
pStartupArgs
->
strDosProtect
);
cmdline
.
AddOption
(
"configfile"
,
required_argument
,
&
pStartupArgs
->
strConfigFile
);
cmdline
.
ParseCommandLine
(
argc
,
argv
,
startindex
,
&
fError
);
...
...
@@ -534,6 +539,79 @@ HRESULT ParseCommandLineArgs(int argc, char** argv, int startindex, StartupArgs*
}
HRESULT
LoadConfigsFromFile
(
const
std
::
string
&
filename
,
std
::
vector
<
StartupArgs
>&
configurations
)
{
ptree
tree
;
bool
error
=
false
;
std
::
string
errorMessage
;
/* EXAMPLE configuration file
{
"configurations": [
{
"description" : "UDP Full Mode listening on default ports",
"mode": "full",
"family": "4",
"protocol": "udp",
"ddp": "1"
},
{
"description" : "TCP Full Mode listening on default port",
"mode": "full",
"family": "6",
"protocol": "tcp",
"ddp": "1"
}
]
}
*/
try
{
read_json
(
filename
,
tree
);
ptree
root
=
tree
.
get_child
(
"configurations"
);
for
(
ptree
::
iterator
itor
=
root
.
begin
();
itor
!=
root
.
end
();
itor
++
)
{
const
ptree
&
child
=
itor
->
second
;
StartupArgs
args
;
args
.
strMode
=
child
.
get
(
"mode"
,
""
);
args
.
strPrimaryInterface
=
child
.
get
(
"primaryinterface"
,
""
);
args
.
strAltInterface
=
child
.
get
(
"altinterface"
,
""
);
args
.
strPrimaryAdvertised
=
child
.
get
(
"primaryadvertised"
,
""
);
args
.
strAlternateAdvertised
=
child
.
get
(
"altadvertised"
,
""
);
args
.
strPrimaryPort
=
child
.
get
(
"primaryport"
,
""
);
args
.
strAltPort
=
child
.
get
(
"altport"
,
""
);
args
.
strFamily
=
child
.
get
(
"family"
,
""
);
args
.
strProtocol
=
child
.
get
(
"protocol"
,
""
);
args
.
strMaxConnections
=
child
.
get
(
"maxconn"
,
""
);
args
.
strDosProtect
=
child
.
get
(
"ddp"
,
""
);
configurations
.
push_back
(
args
);
}
}
catch
(
ptree_error
ex1
)
{
Logging
::
LogMsg
(
LL_ALWAYS
,
"Error processing configuration file: %s"
,
ex1
.
what
());
error
=
true
;
}
if
(
!
error
&&
configurations
.
size
()
==
0
)
{
Logging
::
LogMsg
(
LL_ALWAYS
,
"File is valid json, but no configurations found"
);
error
=
true
;
}
if
(
error
)
{
configurations
.
clear
();
return
E_FAIL
;
}
return
S_OK
;
}
HRESULT
BlockSignal
(
int
sig
)
{
HRESULT
hr
=
S_OK
;
...
...
@@ -589,7 +667,7 @@ HRESULT StartUDP(CRefCountedPtr<CStunServer>& spServer, CStunServerConfig& confi
hr
=
CStunServer
::
CreateInstance
(
config
,
spServer
.
GetPointerPointer
());
if
(
FAILED
(
hr
))
{
Logging
::
LogMsg
(
LL_ALWAYS
,
"Unable to initialize server (error code = x%x)"
,
hr
);
Logging
::
LogMsg
(
LL_ALWAYS
,
"Unable to initialize
UDP
server (error code = x%x)"
,
hr
);
LogHR
(
LL_ALWAYS
,
hr
);
return
hr
;
}
...
...
@@ -597,10 +675,11 @@ HRESULT StartUDP(CRefCountedPtr<CStunServer>& spServer, CStunServerConfig& confi
hr
=
spServer
->
Start
();
if
(
FAILED
(
hr
))
{
Logging
::
LogMsg
(
LL_ALWAYS
,
"Unable to start server (error code = x%x)"
,
hr
);
Logging
::
LogMsg
(
LL_ALWAYS
,
"Unable to start
UDP
server (error code = x%x)"
,
hr
);
LogHR
(
LL_ALWAYS
,
hr
);
return
hr
;
}
sleep
(
1
);
return
S_OK
;
}
...
...
@@ -625,6 +704,8 @@ HRESULT StartTCP(CRefCountedPtr<CTCPServer>& spTCPServer, CStunServerConfig& con
return
hr
;
}
sleep
(
1
);
return
S_OK
;
}
...
...
@@ -633,9 +714,22 @@ int main(int argc, char** argv)
{
HRESULT
hr
=
S_OK
;
StartupArgs
args
;
CStunServerConfig
config
;
CRefCountedPtr
<
CStunServer
>
spServer
;
CRefCountedPtr
<
CTCPServer
>
spTCPServer
;
std
::
vector
<
StartupArgs
>
argsVector
;
int
serverindex
=
1
;
typedef
CRefCountedPtr
<
CStunServer
>
UdpServerPtr
;
typedef
CRefCountedPtr
<
CTCPServer
>
TcpServerPtr
;
std
::
vector
<
UdpServerPtr
>
udpServers
;
std
::
vector
<
TcpServerPtr
>
tcpServers
;
// block sigpipe so that socket send calls from raising SIGPIPE
signal
(
SIGPIPE
,
SIG_IGN
);
BlockSignal
(
SIGPIPE
);
// Block SIGTERM and SIGINT such that the child threads will never get that signal (so that subsequent WaitForAppExitSignal hooks on *this* thread)
BlockSignal
(
SIGTERM
);
BlockSignal
(
SIGINT
);
#ifdef DEBUG
...
...
@@ -667,69 +761,92 @@ int main(int argc, char** argv)
Logging
::
SetLogLevel
((
uint32_t
)
loglevel
);
}
}
if
(
SUCCEEDED
(
hr
))
{
::
DumpStartupArgs
(
args
);
hr
=
BuildServerConfigurationFromArgs
(
args
,
&
config
);
}
if
(
FAILED
(
hr
))
{
Logging
::
LogMsg
(
LL_ALWAYS
,
"Error building configuration from command line options"
);
PrintUsage
(
true
);
return
-
3
;
}
DumpConfig
(
config
);
// block sigpipe so that socket send calls from raising SIGPIPE
signal
(
SIGPIPE
,
SIG_IGN
);
BlockSignal
(
SIGPIPE
);
// Block SIGTERM and SIGINT such that the child threads will never get that signal (so that subsequent WaitForAppExitSignal hooks on *this* thread)
BlockSignal
(
SIGTERM
);
BlockSignal
(
SIGINT
);
if
(
config
.
fTCP
==
false
)
if
(
args
.
strConfigFile
.
empty
()
==
false
)
{
hr
=
StartUDP
(
spServer
,
config
);
hr
=
LoadConfigsFromFile
(
args
.
strConfigFile
,
argsVector
);
if
(
FAILED
(
hr
))
{
return
-
4
;
Logging
::
LogMsg
(
LL_ALWAYS
,
"Can't process configuration file"
);
return
-
3
;
}
}
else
{
hr
=
StartTCP
(
spTCPServer
,
config
);
if
(
FAILED
(
hr
))
argsVector
.
push_back
(
args
);
}
if
(
SUCCEEDED
(
hr
))
{
for
(
std
::
vector
<
StartupArgs
>::
iterator
itor
=
argsVector
.
begin
();
itor
!=
argsVector
.
end
();
itor
++
)
{
return
-
5
;
CStunServerConfig
config
;
StartupArgs
args
=
*
itor
;
Logging
::
LogMsg
(
LL_DEBUG
,
"Starting server %d"
,
serverindex
);
serverindex
++
;
::
DumpStartupArgs
(
args
);
hr
=
BuildServerConfigurationFromArgs
(
args
,
&
config
);
if
(
FAILED
(
hr
))
{
Logging
::
LogMsg
(
LL_ALWAYS
,
"Error building configuration from options given"
);
break
;
}
DumpConfig
(
config
);
if
(
config
.
fTCP
)
{
TcpServerPtr
spTcpServer
;
hr
=
StartTCP
(
spTcpServer
,
config
);
if
(
SUCCEEDED
(
hr
))
{
tcpServers
.
push_back
(
spTcpServer
);
}
}
else
{
UdpServerPtr
spUdpServer
;
hr
=
StartUDP
(
spUdpServer
,
config
);
if
(
SUCCEEDED
(
hr
))
{
udpServers
.
push_back
(
spUdpServer
);
}
}
if
(
FAILED
(
hr
))
{
break
;
}
}
}
Logging
::
LogMsg
(
LL_DEBUG
,
"Successfully started server."
);
if
(
SUCCEEDED
(
hr
))
{
Logging
::
LogMsg
(
LL_DEBUG
,
"Successfully started server."
);
WaitForAppExitSignal
();
}
WaitForAppExitSignal
();
Logging
::
LogMsg
(
LL_DEBUG
,
"Server is exiting"
);
if
(
spServer
!=
NULL
)
for
(
std
::
vector
<
UdpServerPtr
>::
iterator
itor
=
udpServers
.
begin
();
itor
!=
udpServers
.
end
();
itor
++
)
{
spServer
->
Stop
();
spServer
.
ReleaseAndClear
();
Logging
::
LogMsg
(
LL_DEBUG
,
"Shutting down UDP server"
);
UdpServerPtr
server
=
*
itor
;
server
->
Stop
();
}
if
(
spTCPServer
!=
NULL
)
for
(
std
::
vector
<
TcpServerPtr
>::
iterator
itor
=
tcpServers
.
begin
();
itor
!=
tcpServers
.
end
();
itor
++
)
{
spTCPServer
->
Stop
();
spTCPServer
.
ReleaseAndClear
();
Logging
::
LogMsg
(
LL_DEBUG
,
"Shutting down TCP server"
);
TcpServerPtr
server
=
*
itor
;
server
->
Stop
();
}
return
0
;
}
testcode/stun.conf
0 → 100644
View file @
3d23f8f8
{
"configurations"
: [
{
"_description"
:
"STUN over UDP on IPv4 on default ports (basic mode)"
,
"mode"
:
"basic"
,
"primaryinterface"
:
""
,
"secondaryinterface"
:
""
,
"primaryport"
:
"3478"
,
"secondaryport"
:
"3479"
,
"family"
:
"4"
,
"protocol"
:
"udp"
,
"maxconn"
:
""
,
"primaryadvertised"
:
""
,
"altadvertised"
:
""
,
"ddp"
:
"1"
},
{
"_description"
:
"STUN over UDP on IPv6 on default ports (basic mode)"
,
"mode"
:
"basic"
,
"primaryinterface"
:
""
,
"secondaryinterface"
:
""
,
"primaryport"
:
"3478"
,
"secondaryport"
:
"3479"
,
"family"
:
"6"
,
"protocol"
:
"udp"
,
"maxconn"
:
""
,
"primaryadvertised"
:
""
,
"altadvertised"
:
""
,
"ddp"
:
"1"
}
]
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment