Skip to content

Commit 827ffea

Browse files
redboltzkleunen
authored andcommitted
Broker command line options and build executable
1 parent 89003fa commit 827ffea

11 files changed

+232
-47
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,10 @@ FIND_PACKAGE (Threads REQUIRED)
123123

124124
IF (MQTT_USE_LOG)
125125
MESSAGE (STATUS "Logging enabled")
126-
FIND_PACKAGE (Boost 1.67.0 REQUIRED COMPONENTS system date_time log filesystem thread)
126+
FIND_PACKAGE (Boost 1.67.0 REQUIRED COMPONENTS system date_time log filesystem thread program_options)
127127
ELSE ()
128128
MESSAGE (STATUS "Logging disabled")
129-
FIND_PACKAGE (Boost 1.67.0 REQUIRED COMPONENTS system date_time)
129+
FIND_PACKAGE (Boost 1.67.0 REQUIRED COMPONENTS system date_time program_options)
130130
ENDIF ()
131131

132132
IF (MQTT_USE_TLS)

example/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,15 @@ FOREACH (source_file ${exec_PROGRAMS})
5454
TARGET_COMPILE_DEFINITIONS (${source_file_we} PUBLIC $<IF:$<BOOL:${MQTT_USE_STATIC_BOOST}>,,BOOST_LOG_DYN_LINK>)
5555
TARGET_LINK_LIBRARIES (${source_file_we} Boost::log)
5656
ENDIF ()
57+
TARGET_COMPILE_DEFINITIONS (${source_file_we} PUBLIC $<IF:$<BOOL:${MQTT_USE_STATIC_BOOST}>,,BOOST_PROGRAM_OPTIONS_DYN_LINK>)
58+
TARGET_LINK_LIBRARIES (${source_file_we} Boost::program_options)
5759
ENDFOREACH ()
5860

61+
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../example/broker.conf DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
62+
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/server.crt.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
63+
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/server.key.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
64+
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/cacert.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
65+
5966
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
6067
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/mosquitto.org.crt DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/Release)
6168
FILE(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../test/certs/server.crt.pem DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/Release)

example/broker.conf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Default configuration for MQTT-CPP Broker
2+
verbose=1
3+
certificate=broker.crt.pem
4+
private_key=broker.key.pem
5+
6+
# Configuration for TCP
7+
[tcp]
8+
port=1883
9+
10+
# Configuration for TLS
11+
[tls]
12+
# port=8883
13+
14+
# Configuration for Websocket
15+
[ws]
16+
# port=10080
17+
18+
# Configuration for Websocket with TLS
19+
[wss]
20+
# port=10433

example/broker.cpp

Lines changed: 159 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,167 @@
55
// http://www.boost.org/LICENSE_1_0.txt)
66

77
#include <mqtt/config.hpp>
8-
98
#include "../test/system/test_server_no_tls.hpp"
9+
#include "../test/system/test_server_no_tls_ws.hpp"
10+
#include "../test/system/test_server_tls.hpp"
11+
#include "../test/system/test_server_tls_ws.hpp"
1012
#include <mqtt/setup_log.hpp>
11-
1213
#include <mqtt/broker/broker.hpp>
14+
#include <boost/program_options.hpp>
15+
16+
#include <fstream>
17+
18+
#if defined(MQTT_USE_TLS)
19+
boost::asio::ssl::context init_ctx(boost::program_options::variables_map const& vm)
20+
{
21+
if (vm.count("certificate") == 0 && vm.count("private_key") == 0) {
22+
throw std::runtime_error("TLS requested but certificate and/or private_key not specified");
23+
}
24+
25+
boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12);
26+
ctx.set_options(
27+
boost::asio::ssl::context::default_workarounds |
28+
boost::asio::ssl::context::single_dh_use);
29+
ctx.use_certificate_file(vm["certificate"].as<std::string>(), boost::asio::ssl::context::pem);
30+
ctx.use_private_key_file(vm["private_key"].as<std::string>(), boost::asio::ssl::context::pem);
31+
return ctx;
32+
}
33+
#endif // defined(MQTT_USE_TLS)
34+
35+
void run_broker(boost::program_options::variables_map const& vm)
36+
{
37+
try {
38+
boost::asio::io_context ioc;
39+
MQTT_NS::broker::broker_t b(ioc);
40+
41+
std::unique_ptr<test_server_no_tls> s;
42+
if (vm.count("tcp.port")) {
43+
s = std::make_unique<test_server_no_tls>(ioc, b, vm["tcp.port"].as<uint16_t>());
44+
}
45+
46+
#if defined(MQTT_USE_WS)
47+
std::unique_ptr<test_server_no_tls_ws> s_ws;
48+
if (vm.count("ws.port")) {
49+
s_ws = std::make_unique<test_server_no_tls_ws>(ioc, b, vm["ws.port"].as<uint16_t>());
50+
}
51+
#endif // defined(MQTT_USE_WS)
52+
53+
#if defined(MQTT_USE_TLS)
54+
std::unique_ptr<test_server_tls> s_tls;
55+
if (vm.count("tls.port")) {
56+
s_tls = std::make_unique<test_server_tls>(ioc, init_ctx(vm), b, vm["tls.port"].as<uint16_t>());
57+
}
58+
#endif // defined(MQTT_USE_TLS)
59+
60+
#if defined(MQTT_USE_TLS) && defined(MQTT_USE_WS)
61+
std::unique_ptr<test_server_tls_ws> s_tls_ws;
62+
if (vm.count("wss.port")) {
63+
s_tls_ws = std::make_unique<test_server_tls_ws>(ioc, init_ctx(vm), b, vm["wss.port"].as<uint16_t>());
64+
}
65+
#endif // defined(MQTT_USE_TLS) && defined(MQTT_USE_WS)
66+
67+
68+
ioc.run();
69+
} catch(std::exception &e) {
70+
MQTT_LOG("mqtt_broker", error) << e.what();
71+
}
72+
}
73+
74+
int main(int argc, char **argv) {
75+
try {
76+
boost::program_options::options_description desc;
77+
78+
boost::program_options::options_description general_desc("General options");
79+
general_desc.add_options()
80+
("help", "produce help message")
81+
("cfg", boost::program_options::value<std::string>()->default_value("broker.conf"), "Load configuration file")
82+
#if defined(MQTT_USE_LOG)
83+
("verbose", boost::program_options::value<unsigned int>()->default_value(1), "set verbose level, possible values:\n 0 - Fatal\n 1 - Error\n 2 - Warning\n 3 - Info\n 4 - Debug\n 5 - Trace")
84+
#endif // defined(MQTT_USE_LOG)
85+
("certificate", boost::program_options::value<std::string>(), "Certificate file for TLS connections")
86+
("private_key", boost::program_options::value<std::string>(), "Private key file for TLS connections")
87+
;
88+
89+
boost::program_options::options_description notls_desc("TCP Server options");
90+
notls_desc.add_options()
91+
("tcp.port", boost::program_options::value<uint16_t>(), "default port (TCP)")
92+
;
93+
desc.add(general_desc).add(notls_desc);
94+
95+
#if defined(MQTT_USE_WS)
96+
boost::program_options::options_description ws_desc("TCP websocket Server options");
97+
ws_desc.add_options()
98+
("ws.port", boost::program_options::value<uint16_t>(), "default port (TCP)")
99+
;
100+
101+
desc.add(ws_desc);
102+
#endif // defined(MQTT_USE_WS)
103+
104+
#if defined(MQTT_USE_TLS)
105+
boost::program_options::options_description tls_desc("TLS Server options");
106+
tls_desc.add_options()
107+
("tls.port", boost::program_options::value<uint16_t>(), "default port (TLS)")
108+
;
109+
110+
desc.add(tls_desc);
111+
#endif // defined(MQTT_USE_TLS)
112+
113+
#if defined(MQTT_USE_WS) && defined(MQTT_USE_TLS)
114+
boost::program_options::options_description tlsws_desc("TLS Websocket Server options");
115+
tlsws_desc.add_options()
116+
("wss.port", boost::program_options::value<uint16_t>(), "default port (TLS)")
117+
;
118+
desc.add(tlsws_desc);
119+
#endif // defined(MQTT_USE_TLS) && defined(MQTT_USE_WS)
120+
121+
boost::program_options::variables_map vm;
122+
boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
123+
124+
std::string config_file = vm["cfg"].as<std::string>();
125+
if (!config_file.empty()) {
126+
std::ifstream input(vm["cfg"].as<std::string>());
127+
if (input.good()) {
128+
boost::program_options::store(boost::program_options::parse_config_file(input, desc), vm);
129+
} else
130+
{
131+
std::cerr << "Configuration file '" << config_file << "' not found, broker doesn't use configuration file." << std::endl;
132+
}
133+
}
134+
135+
boost::program_options::notify(vm);
136+
137+
if (vm.count("help")) {
138+
std::cout << desc << std::endl;
139+
return 1;
140+
}
141+
142+
#if defined(MQTT_USE_LOG)
143+
switch (vm["verbose"].as<unsigned int>()) {
144+
case 5:
145+
MQTT_NS::setup_log(mqtt::severity_level::trace);
146+
break;
147+
case 4:
148+
MQTT_NS::setup_log(mqtt::severity_level::debug);
149+
break;
150+
case 3:
151+
MQTT_NS::setup_log(mqtt::severity_level::info);
152+
break;
153+
case 2:
154+
MQTT_NS::setup_log(mqtt::severity_level::warning);
155+
break;
156+
default:
157+
MQTT_NS::setup_log(mqtt::severity_level::error);
158+
break;
159+
case 0:
160+
MQTT_NS::setup_log(mqtt::severity_level::fatal);
161+
break;
162+
}
163+
#else
164+
MQTT_NS::setup_log();
165+
#endif
13166

14-
int main() {
15-
MQTT_NS::setup_log();
16-
boost::asio::io_context ioc;
17-
MQTT_NS::broker::broker_t b(ioc);
18-
test_server_no_tls s(ioc, b);
19-
ioc.run();
167+
run_broker(vm);
168+
} catch(std::exception &e) {
169+
std::cerr << e.what() << std::endl;
170+
}
20171
}

test/system/combi_test.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "test_server_no_tls.hpp"
1717
#if defined(MQTT_USE_TLS)
1818
#include "test_server_tls.hpp"
19+
#include "test_ctx_init.hpp"
1920
#endif // defined(MQTT_USE_TLS)
2021

2122
#if defined(MQTT_USE_WS)
@@ -91,7 +92,7 @@ inline void do_tls_test(
9192
auto f = p.get_future();
9293
std::thread th(
9394
[&] {
94-
s.emplace(iocb, b);
95+
s.emplace(iocb, test_ctx_init(), b);
9596
p.set_value();
9697
iocb.run();
9798
}
@@ -193,7 +194,7 @@ inline void do_tls_ws_test(
193194
auto f = p.get_future();
194195
std::thread th(
195196
[&] {
196-
s.emplace(iocb, b);
197+
s.emplace(iocb, test_ctx_init(), b);
197198
p.set_value();
198199
iocb.run();
199200
}

test/system/st_underlying_timeout.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,11 @@ BOOST_AUTO_TEST_CASE( connect_tls_ws_ashs ) {
8787
as::io_context ioc;
8888

8989
// server
90-
ctx_init ci;
9190
MQTT_NS::server_tls_ws<> server(
9291
as::ip::tcp::endpoint(
9392
as::ip::tcp::v4(),
9493
broker_tls_ws_port),
95-
std::move(ci.ctx),
94+
test_ctx_init(),
9695
ioc);
9796

9897
server.set_accept_handler(
@@ -153,12 +152,11 @@ BOOST_AUTO_TEST_CASE( connect_tls_ws_upg ) {
153152
as::io_context ioc;
154153

155154
// server
156-
ctx_init ci;
157155
MQTT_NS::server_tls_ws<> server(
158156
as::ip::tcp::endpoint(
159157
as::ip::tcp::v4(),
160158
broker_tls_ws_port),
161-
std::move(ci.ctx),
159+
test_ctx_init(),
162160
ioc);
163161

164162
server.set_accept_handler(
@@ -236,12 +234,11 @@ BOOST_AUTO_TEST_CASE( connect_tls_ashs ) {
236234
as::io_context ioc;
237235

238236
// server
239-
ctx_init ci;
240237
MQTT_NS::server_tls<> server(
241238
as::ip::tcp::endpoint(
242239
as::ip::tcp::v4(),
243240
broker_tls_port),
244-
std::move(ci.ctx),
241+
test_ctx_init(),
245242
ioc);
246243

247244
server.set_accept_handler(

test/system/test_ctx_init.hpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@
1414

1515
#include "test_settings.hpp"
1616

17-
struct ctx_init {
18-
ctx_init() : ctx(boost::asio::ssl::context::tlsv12) {
19-
ctx.set_options(
20-
boost::asio::ssl::context::default_workarounds |
21-
boost::asio::ssl::context::single_dh_use);
22-
std::string path = boost::unit_test::framework::master_test_suite().argv[0];
23-
std::size_t pos = path.find_last_of("/\\");
24-
std::string base = (pos == std::string::npos) ? "" : path.substr(0, pos + 1);
25-
ctx.use_certificate_file(base + "server.crt.pem", boost::asio::ssl::context::pem);
26-
ctx.use_private_key_file(base + "server.key.pem", boost::asio::ssl::context::pem);
27-
}
28-
boost::asio::ssl::context ctx;
29-
};
17+
static inline boost::asio::ssl::context test_ctx_init() {
18+
boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12);
19+
ctx.set_options(
20+
boost::asio::ssl::context::default_workarounds |
21+
boost::asio::ssl::context::single_dh_use);
22+
std::string path = boost::unit_test::framework::master_test_suite().argv[0];
23+
std::size_t pos = path.find_last_of("/\\");
24+
std::string base = (pos == std::string::npos) ? "" : path.substr(0, pos + 1);
25+
ctx.use_certificate_file(base + "server.crt.pem", boost::asio::ssl::context::pem);
26+
ctx.use_private_key_file(base + "server.key.pem", boost::asio::ssl::context::pem);
27+
return ctx;
28+
}
29+
3030

3131
#endif // defined(MQTT_USE_TLS)
3232

test/system/test_server_no_tls.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ using con_sp_t = std::shared_ptr<con_t>;
2121

2222
class test_server_no_tls {
2323
public:
24-
test_server_no_tls(as::io_context& ioc, MQTT_NS::broker::broker_t& b)
24+
test_server_no_tls(as::io_context& ioc, MQTT_NS::broker::broker_t& b, uint16_t port = broker_notls_port)
2525
: server_(
2626
as::ip::tcp::endpoint(
27-
as::ip::tcp::v4(), broker_notls_port
27+
as::ip::tcp::v4(), port
2828
),
2929
ioc,
3030
ioc,

test/system/test_server_no_tls_ws.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#if !defined(MQTT_TEST_SERVER_NO_TLS_WS_HPP)
88
#define MQTT_TEST_SERVER_NO_TLS_WS_HPP
99

10+
#if defined(MQTT_USE_WS)
1011
#include <mqtt_server_cpp.hpp>
1112

1213
#include <mqtt/broker/broker.hpp>
@@ -15,13 +16,12 @@
1516
namespace mi = boost::multi_index;
1617
namespace as = boost::asio;
1718

18-
1919
class test_server_no_tls_ws {
2020
public:
21-
test_server_no_tls_ws(as::io_context& ioc, MQTT_NS::broker::broker_t& b)
21+
test_server_no_tls_ws(as::io_context& ioc, MQTT_NS::broker::broker_t& b, uint16_t port = broker_notls_ws_port)
2222
: server_(
2323
as::ip::tcp::endpoint(
24-
as::ip::tcp::v4(), broker_notls_ws_port
24+
as::ip::tcp::v4(), port
2525
),
2626
ioc,
2727
ioc,
@@ -56,4 +56,6 @@ class test_server_no_tls_ws {
5656
MQTT_NS::broker::broker_t& b_;
5757
};
5858

59+
#endif // defined(MQTT_USE_WS)
60+
5961
#endif // MQTT_TEST_SERVER_NO_TLS_WS_HPP

0 commit comments

Comments
 (0)