diff options
Diffstat (limited to '')
-rw-r--r-- | src/seastar/demos/tls_simple_client_demo.cc | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/src/seastar/demos/tls_simple_client_demo.cc b/src/seastar/demos/tls_simple_client_demo.cc new file mode 100644 index 000000000..d53461b0e --- /dev/null +++ b/src/seastar/demos/tls_simple_client_demo.cc @@ -0,0 +1,133 @@ +/* + * This file is open source software, licensed to you under the terms + * of the Apache License, Version 2.0 (the "License"). See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. You may not use this file except in compliance with the License. + * + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +/* + * Copyright 2015 Cloudius Systems + */ +#include <cmath> + +#include <seastar/core/shared_ptr.hh> +#include <seastar/core/reactor.hh> +#include <seastar/core/app-template.hh> +#include <seastar/core/sleep.hh> +#include <seastar/core/loop.hh> +#include <seastar/net/dns.hh> +#include "tls_echo_server.hh" + +using namespace seastar; +namespace bpo = boost::program_options; + + +int main(int ac, char** av) { + app_template app; + app.add_options() + ("port", bpo::value<uint16_t>()->default_value(10000), "Remote port") + ("address", bpo::value<std::string>()->default_value("127.0.0.1"), "Remote address") + ("trust,t", bpo::value<std::string>(), "Trust store") + ("msg,m", bpo::value<std::string>(), "Message to send") + ("bytes,b", bpo::value<size_t>()->default_value(512), "Use random bytes of length as message") + ("iterations,i", bpo::value<size_t>()->default_value(1), "Repeat X times") + ("read-response,r", bpo::value<bool>()->default_value(true)->implicit_value(true), "Read echoed message") + ("verbose,v", bpo::value<bool>()->default_value(false)->implicit_value(true), "Verbose operation") + ("check-name,c", bpo::value<bool>()->default_value(false)->implicit_value(true), "Check server name") + ("server-name,s", bpo::value<std::string>(), "Expected server name") + ; + + + return app.run_deprecated(ac, av, [&] { + auto&& config = app.configuration(); + uint16_t port = config["port"].as<uint16_t>(); + auto addr = config["address"].as<std::string>(); + auto n = config["bytes"].as<size_t>(); + auto i = config["iterations"].as<size_t>(); + auto do_read = config["read-response"].as<bool>(); + auto verbose = config["verbose"].as<bool>(); + auto check = config["check-name"].as<bool>(); + + std::cout << "Starting..." << std::endl; + + auto certs = ::make_shared<tls::certificate_credentials>(); + auto f = make_ready_future(); + + if (config.count("trust")) { + f = certs->set_x509_trust_file(config["trust"].as<std::string>(), tls::x509_crt_format::PEM); + } + + seastar::shared_ptr<sstring> msg; + + if (config.count("msg")) { + msg = seastar::make_shared<sstring>(config["msg"].as<std::string>()); + } else { + msg = seastar::make_shared<sstring>(uninitialized_string(n)); + for (size_t i = 0; i < n; ++i) { + (*msg)[i] = '0' + char(::rand() % 30); + } + } + + sstring server_name; + if (config.count("server-name")) { + server_name = config["server-name"].as<std::string>(); + } + if (verbose) { + std::cout << "Msg (" << msg->size() << "B):" << std::endl << *msg << std::endl; + } + return f.then([=]() { + return net::dns::get_host_by_name(addr).then([=](net::hostent e) { + ipv4_addr ia(e.addr_list.front(), port); + + sstring name; + if (check) { + name = server_name.empty() ? e.names.front() : server_name; + } + return tls::connect(certs, ia, name).then([=](::connected_socket s) { + auto strms = ::make_lw_shared<streams>(std::move(s)); + auto range = boost::irange(size_t(0), i); + return do_for_each(range, [=](auto) { + auto f = strms->out.write(*msg); + if (!do_read) { + return strms->out.close().then([f = std::move(f)]() mutable { + return std::move(f); + }); + } + return f.then([=]() { + return strms->out.flush().then([=] { + return strms->in.read_exactly(msg->size()).then([=](temporary_buffer<char> buf) { + sstring tmp(buf.begin(), buf.end()); + if (tmp != *msg) { + std::cerr << "Got garbled message!" << std::endl; + if (verbose) { + std::cout << "Got (" << tmp.size() << ") :" << std::endl << tmp << std::endl; + } + throw std::runtime_error("Got garbled message!"); + } + }); + }); + }); + }).then([strms, do_read]{ + return do_read ? strms->out.close() : make_ready_future<>(); + }).finally([strms]{ + return strms->in.close(); + }); + }); + }).handle_exception([](auto ep) { + std::cerr << "Error: " << ep << std::endl; + }); + }).finally([] { + engine().exit(0); + }); + }); +} |