The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
network_asio.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2011 - 2025
3 by Sergey Popov <loonycyborg@gmail.com>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16#pragma once
17
18#ifdef _WIN32
19
20#ifdef INADDR_ANY
21#undef INADDR_ANY
22#endif
23
24#ifdef INADDR_BROADCAST
25#undef INADDR_BROADCAST
26#endif
27
28#ifdef INADDR_NONE
29#undef INADDR_NONE
30#endif
31
32#endif
33
34#include "exceptions.hpp"
35#include "utils/variant.hpp"
36
37#include <boost/asio/io_context.hpp>
38#include <boost/asio/ip/tcp.hpp>
39#include <boost/asio/streambuf.hpp>
40#include <boost/asio/ssl.hpp>
41
42class config;
43
44namespace network_asio
45{
46struct error : public game::error
47{
48 error(const boost::system::error_code& error)
50 {
51 }
52};
53
54/** A class that represents a TCP/IP connection. */
56{
57public:
58 /**
59 * Constructor.
60 *
61 * @param host Name of the host to connect to
62 * @param service Service identifier such as "80" or "http"
63 */
64 connection(const std::string& host, const std::string& service);
66
67 void transfer(const config& request, config& response);
68
69 /** Handle all pending asynchronous events and return */
70 std::size_t poll()
71 {
72 try {
73 return io_context_.poll();
74 } catch(const boost::system::system_error& err) {
75 if(err.code() == boost::asio::error::operation_aborted) {
76 return 1;
77 }
78
79 throw error(err.code());
80 }
81 }
82
83 /**
84 * Run asio's event loop
85 *
86 * Handle asynchronous events blocking until all asynchronous operations have finished.
87 */
88 void run()
89 {
90 io_context_.run();
91 }
92
93 void cancel();
94
95 /** True if connected and no high-level operation is in progress */
96 bool done() const
97 {
98 return done_;
99 }
100
101 /** True if connection is currently using TLS and thus is allowed to send cleartext passwords or auth tokens */
102 bool using_tls() const
103 {
104 // Calling this function before connection is ready may return wrong result
105 assert(done_);
106 return utils::holds_alternative<tls_socket>(socket_);
107 }
108
109 std::size_t bytes_to_write() const
110 {
111 return bytes_to_write_;
112 }
113
114 std::size_t bytes_written() const
115 {
116 return bytes_written_;
117 }
118
119 std::size_t bytes_to_read() const
120 {
121 return bytes_to_read_;
122 }
123
124 std::size_t bytes_read() const
125 {
126 return bytes_read_;
127 }
128
129private:
130 boost::asio::io_context io_context_;
131
132 std::string host_;
133 const std::string service_;
134 typedef boost::asio::ip::tcp::resolver resolver;
136
137 boost::asio::ssl::context tls_context_ { boost::asio::ssl::context::tlsv13_client };
138
139 typedef std::unique_ptr<boost::asio::ip::tcp::socket> raw_socket;
140 typedef std::unique_ptr<boost::asio::ssl::stream<raw_socket::element_type>> tls_socket;
141 typedef utils::variant<raw_socket, tls_socket> any_socket;
144
145 bool done_;
146
147 std::unique_ptr<boost::asio::streambuf> write_buf_;
148 std::unique_ptr<boost::asio::streambuf> read_buf_;
149
150 using results_type = resolver::results_type;
151 using endpoint = const boost::asio::ip::tcp::endpoint&;
152
153 void handle_resolve(const boost::system::error_code& ec, const results_type& results);
154 void handle_connect(const boost::system::error_code& ec, endpoint endpoint);
155
156 void handshake();
157 void handle_handshake(const boost::system::error_code& ec);
158
160
162
163 std::size_t is_write_complete(const boost::system::error_code& error, std::size_t bytes_transferred);
164 void handle_write(const boost::system::error_code& ec, std::size_t bytes_transferred);
165
166 std::size_t is_read_complete(const boost::system::error_code& error, std::size_t bytes_transferred);
167 void handle_read(const boost::system::error_code& ec, std::size_t bytes_transferred, config& response);
168
170
171 std::size_t bytes_to_write_;
172 std::size_t bytes_written_;
173 std::size_t bytes_to_read_;
174 std::size_t bytes_read_;
175};
176}
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
A class that represents a TCP/IP connection.
void handle_write(const boost::system::error_code &ec, std::size_t bytes_transferred)
std::size_t is_read_complete(const boost::system::error_code &error, std::size_t bytes_transferred)
void run()
Run asio's event loop.
std::size_t bytes_to_write() const
utils::variant< raw_socket, tls_socket > any_socket
void transfer(const config &request, config &response)
std::unique_ptr< boost::asio::ssl::stream< raw_socket::element_type > > tls_socket
std::size_t bytes_read() const
resolver::results_type results_type
std::size_t is_write_complete(const boost::system::error_code &error, std::size_t bytes_transferred)
boost::asio::io_context io_context_
void handle_resolve(const boost::system::error_code &ec, const results_type &results)
std::unique_ptr< boost::asio::ip::tcp::socket > raw_socket
void handle_read(const boost::system::error_code &ec, std::size_t bytes_transferred, config &response)
std::unique_ptr< boost::asio::streambuf > write_buf_
void handle_handshake(const boost::system::error_code &ec)
void handle_connect(const boost::system::error_code &ec, endpoint endpoint)
std::size_t poll()
Handle all pending asynchronous events and return.
bool using_tls() const
True if connection is currently using TLS and thus is allowed to send cleartext passwords or auth tok...
boost::asio::ip::tcp::resolver resolver
boost::asio::ssl::context tls_context_
std::size_t bytes_to_read() const
std::size_t bytes_written() const
const boost::asio::ip::tcp::endpoint & endpoint
std::unique_ptr< boost::asio::streambuf > read_buf_
bool done() const
True if connected and no high-level operation is in progress.
const std::string service_
Base class for all the errors encountered by the engine.
std::string message
error(const boost::system::error_code &error)
MacOS doesn't support std::visit when targing MacOS < 10.14 (currently we target 10....