]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/asio/example/cpp03/ssl/server.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / asio / example / cpp03 / ssl / server.cpp
1 //
2 // server.cpp
3 // ~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 #include <cstdlib>
12 #include <iostream>
13 #include <boost/bind.hpp>
14 #include <boost/asio.hpp>
15 #include <boost/asio/ssl.hpp>
16
17 typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
18
19 class session
20 {
21 public:
22 session(boost::asio::io_context& io_context,
23 boost::asio::ssl::context& context)
24 : socket_(io_context, context)
25 {
26 }
27
28 ssl_socket::lowest_layer_type& socket()
29 {
30 return socket_.lowest_layer();
31 }
32
33 void start()
34 {
35 socket_.async_handshake(boost::asio::ssl::stream_base::server,
36 boost::bind(&session::handle_handshake, this,
37 boost::asio::placeholders::error));
38 }
39
40 void handle_handshake(const boost::system::error_code& error)
41 {
42 if (!error)
43 {
44 socket_.async_read_some(boost::asio::buffer(data_, max_length),
45 boost::bind(&session::handle_read, this,
46 boost::asio::placeholders::error,
47 boost::asio::placeholders::bytes_transferred));
48 }
49 else
50 {
51 delete this;
52 }
53 }
54
55 void handle_read(const boost::system::error_code& error,
56 size_t bytes_transferred)
57 {
58 if (!error)
59 {
60 boost::asio::async_write(socket_,
61 boost::asio::buffer(data_, bytes_transferred),
62 boost::bind(&session::handle_write, this,
63 boost::asio::placeholders::error));
64 }
65 else
66 {
67 delete this;
68 }
69 }
70
71 void handle_write(const boost::system::error_code& error)
72 {
73 if (!error)
74 {
75 socket_.async_read_some(boost::asio::buffer(data_, max_length),
76 boost::bind(&session::handle_read, this,
77 boost::asio::placeholders::error,
78 boost::asio::placeholders::bytes_transferred));
79 }
80 else
81 {
82 delete this;
83 }
84 }
85
86 private:
87 ssl_socket socket_;
88 enum { max_length = 1024 };
89 char data_[max_length];
90 };
91
92 class server
93 {
94 public:
95 server(boost::asio::io_context& io_context, unsigned short port)
96 : io_context_(io_context),
97 acceptor_(io_context,
98 boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
99 context_(boost::asio::ssl::context::sslv23)
100 {
101 context_.set_options(
102 boost::asio::ssl::context::default_workarounds
103 | boost::asio::ssl::context::no_sslv2
104 | boost::asio::ssl::context::single_dh_use);
105 context_.set_password_callback(boost::bind(&server::get_password, this));
106 context_.use_certificate_chain_file("server.pem");
107 context_.use_private_key_file("server.pem", boost::asio::ssl::context::pem);
108 context_.use_tmp_dh_file("dh2048.pem");
109
110 start_accept();
111 }
112
113 std::string get_password() const
114 {
115 return "test";
116 }
117
118 void start_accept()
119 {
120 session* new_session = new session(io_context_, context_);
121 acceptor_.async_accept(new_session->socket(),
122 boost::bind(&server::handle_accept, this, new_session,
123 boost::asio::placeholders::error));
124 }
125
126 void handle_accept(session* new_session,
127 const boost::system::error_code& error)
128 {
129 if (!error)
130 {
131 new_session->start();
132 }
133 else
134 {
135 delete new_session;
136 }
137
138 start_accept();
139 }
140
141 private:
142 boost::asio::io_context& io_context_;
143 boost::asio::ip::tcp::acceptor acceptor_;
144 boost::asio::ssl::context context_;
145 };
146
147 int main(int argc, char* argv[])
148 {
149 try
150 {
151 if (argc != 2)
152 {
153 std::cerr << "Usage: server <port>\n";
154 return 1;
155 }
156
157 boost::asio::io_context io_context;
158
159 using namespace std; // For atoi.
160 server s(io_context, atoi(argv[1]));
161
162 io_context.run();
163 }
164 catch (std::exception& e)
165 {
166 std::cerr << "Exception: " << e.what() << "\n";
167 }
168
169 return 0;
170 }