Skip to content

Commit

Permalink
Merge pull request #961 from redboltz/add_tls_sni_example
Browse files Browse the repository at this point in the history
Added example for TLS-SNI.
  • Loading branch information
redboltz authored Oct 20, 2022
2 parents 0d9e718 + 44a490a commit 3b1dfe2
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 0 deletions.
1 change: 1 addition & 0 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ FIND_PACKAGE (Boost 1.74.0 REQUIRED COMPONENTS program_options)
IF (MQTT_USE_TLS)
LIST (APPEND exec_PROGRAMS
tls_client.cpp
tls_client_with_sni.cpp
tls_server.cpp
tls_both.cpp
tls_both_client_cert.cpp
Expand Down
154 changes: 154 additions & 0 deletions example/tls_client_with_sni.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// Copyright Takatoshi Kondo 2015
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include <iostream>
#include <iomanip>
#include <map>

#include <mqtt_client_cpp.hpp>

int main(int argc, char** argv) {
if (argc != 4) {
std::cout << argv[0] << " host port cacert_file" << std::endl;
return -1;
}

MQTT_NS::setup_log();

boost::asio::io_context ioc;

std::string host = argv[1];
auto port = argv[2];
std::string cacert = argv[3];

std::uint16_t pid_sub1;
std::uint16_t pid_sub2;

int count = 0;

// Create TLS client
auto c = MQTT_NS::make_tls_sync_client(ioc, host, port);
using packet_id_t = typename std::remove_reference_t<decltype(*c)>::packet_id_t;

auto connect =
[&] {
// create custom socket
auto stream =
std::make_shared<
MQTT_NS::tcp_endpoint<
MQTT_NS::tls::stream<boost::asio::ip::tcp::socket>,
MQTT_NS::strand
>
>(ioc, c->get_ssl_context());

if (!SSL_set_tlsext_host_name(MQTT_NS::any_cast<SSL*>(stream->native_handle()), host.c_str())) {
std::cout << "SSL_set_tlsext_host_name return false" << std::endl;
return false;
}
c->connect(MQTT_NS::force_move(stream));
return true;
};

auto disconnect = [&] {
if (++count == 5) c->disconnect();
};

// Setup client
c->set_client_id("cid1");
c->set_clean_session(true);
c->get_ssl_context().load_verify_file(cacert);

// Setup handlers
c->set_connack_handler(
[&c, &pid_sub1, &pid_sub2]
(bool sp, MQTT_NS::connect_return_code connack_return_code){
std::cout << "Connack handler called" << std::endl;
std::cout << "Session Present: " << std::boolalpha << sp << std::endl;
std::cout << "Connack Return Code: "
<< MQTT_NS::connect_return_code_to_str(connack_return_code) << std::endl;
if (connack_return_code == MQTT_NS::connect_return_code::accepted) {
pid_sub1 = c->subscribe("mqtt_client_cpp/topic1", MQTT_NS::qos::at_most_once);
pid_sub2 = c->subscribe(
std::vector<std::tuple<MQTT_NS::string_view, MQTT_NS::subscribe_options>>
{
{ "mqtt_client_cpp/topic2_1", MQTT_NS::subscribe_options(MQTT_NS::qos::at_least_once) },
{ "mqtt_client_cpp/topic2_2", MQTT_NS::subscribe_options(MQTT_NS::qos::exactly_once) }
}
);
}
return true;
});
c->set_close_handler(
[]
(){
std::cout << "closed." << std::endl;
});
c->set_error_handler(
[]
(MQTT_NS::error_code ec){
std::cout << "error: " << ec.message() << std::endl;
});
c->set_puback_handler(
[&]
(packet_id_t packet_id){
std::cout << "puback received. packet_id: " << packet_id << std::endl;
disconnect();
return true;
});
c->set_pubrec_handler(
[&]
(packet_id_t packet_id){
std::cout << "pubrec received. packet_id: " << packet_id << std::endl;
return true;
});
c->set_pubcomp_handler(
[&]
(packet_id_t packet_id){
std::cout << "pubcomp received. packet_id: " << packet_id << std::endl;
disconnect();
return true;
});
c->set_suback_handler(
[&]
(packet_id_t packet_id, std::vector<MQTT_NS::suback_return_code> results){
std::cout << "suback received. packet_id: " << packet_id << std::endl;
for (auto const& e : results) {
std::cout << "[client] subscribe result: " << e << std::endl;
}
if (packet_id == pid_sub1) {
c->publish("mqtt_client_cpp/topic1", "test1", MQTT_NS::qos::at_most_once);
}
else if (packet_id == pid_sub2) {
c->publish("mqtt_client_cpp/topic2_1", "test2_1", MQTT_NS::qos::at_least_once);
c->publish("mqtt_client_cpp/topic2_2", "test2_2", MQTT_NS::qos::exactly_once);
}
return true;
});
c->set_publish_handler(
[&]
(MQTT_NS::optional<packet_id_t> packet_id,
MQTT_NS::publish_options pubopts,
MQTT_NS::buffer topic_name,
MQTT_NS::buffer contents){
std::cout << "publish received."
<< " dup: " << pubopts.get_dup()
<< " qos: " << pubopts.get_qos()
<< " retain: " << pubopts.get_retain() << std::endl;
if (packet_id)
std::cout << "packet_id: " << *packet_id << std::endl;
std::cout << "topic_name: " << topic_name << std::endl;
std::cout << "contents: " << contents << std::endl;
disconnect();
return true;
});

// Connect
if (!connect()) {
std::cout << "connect failed" << std::endl;
}

ioc.run();
}

0 comments on commit 3b1dfe2

Please sign in to comment.