The Battle for Wesnoth  1.17.0-dev
server.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2021
3  by David White <dave@whitevine.net>
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 #include "config.hpp"
21 #include "server/wesnothd/ban.hpp"
26 
27 #include <boost/asio/steady_timer.hpp>
28 
29 #include <optional>
30 #include <random>
31 
32 namespace wesnothd
33 {
34 
35 class server : public server_base
36 {
37 public:
38  server(int port, bool keep_alive, const std::string& config_file, std::size_t, std::size_t);
39 
40  // We keep this flag for coroutines. Since they get their stack unwinding done after player_connections_
41  // is already destroyed they need to know to avoid calling remove_player() on invalid iterators.
42  bool destructed = false;
43  ~server() {
44  destructed = true;
45  }
46 
47 private:
48  void handle_new_client(socket_ptr socket);
49  void handle_new_client(tls_socket_ptr socket);
50 
51  template<class SocketPtr> void login_client(boost::asio::yield_context yield, SocketPtr socket);
52  template<class SocketPtr> bool is_login_allowed(SocketPtr socket, const simple_wml::node* const login, const std::string& username, bool& registered, bool& is_moderator);
53  template<class SocketPtr> bool authenticate(SocketPtr socket, const std::string& username, const std::string& password, bool name_taken, bool& registered);
54  template<class SocketPtr> void send_password_request(SocketPtr socket, const std::string& msg, const char* error_code = "", bool force_confirmation = false);
55  bool accepting_connections() const { return !graceful_restart; }
56 
57  template<class SocketPtr> void handle_player(boost::asio::yield_context yield, SocketPtr socket, const player& player);
60  void handle_whisper(player_iterator player, simple_wml::node& whisper);
61  void handle_query(player_iterator player, simple_wml::node& query);
62  void handle_nickserv(player_iterator player, simple_wml::node& nickserv);
63  void handle_message(player_iterator player, simple_wml::node& message);
64  void handle_create_game(player_iterator player, simple_wml::node& create_game);
65  void cleanup_game(game*); // deleter for shared_ptr
68  void remove_player(player_iterator player);
69 
70 public:
71  template<class SocketPtr> void send_server_message(SocketPtr socket, const std::string& message, const std::string& type);
72  void send_server_message(player_iterator player, const std::string& message, const std::string& type) {
73  utils::visit(
74  [this, &message, &type](auto&& socket) { send_server_message(socket, message, type); },
75  player->socket()
76  );
77  }
78  void send_to_lobby(simple_wml::document& data, std::optional<player_iterator> exclude = {});
80  utils::visit(
81  [this, &data](auto&& socket) { async_send_doc_queued(socket, data); },
82  player->socket()
83  );
84  }
85  void send_server_message_to_lobby(const std::string& message, std::optional<player_iterator> exclude = {});
86  void send_server_message_to_all(const std::string& message, std::optional<player_iterator> exclude = {});
87 
88  bool player_is_in_game(player_iterator player) const {
89  return player->get_game() != nullptr;
90  }
91 
92 private:
94 
96  {
97  std::string nick, ip;
98  std::time_t log_off;
99 
100  bool operator==(const connection_log& c) const
101  {
102  // log off time does not matter to find ip-nick pairs
103  return c.nick == nick && c.ip == ip;
104  }
105  };
106 
107  std::deque<connection_log> ip_log_;
108 
109  struct login_log
110  {
111  std::string ip;
112  int attempts;
113  std::time_t first_attempt;
114 
115  bool operator==(const login_log& l) const
116  {
117  // only the IP matters
118  return l.ip == ip;
119  }
120  };
121 
122  std::deque<login_log> failed_logins_;
123 
124  std::unique_ptr<user_handler> user_handler_;
125 
126  std::mt19937 die_;
127 
128 #ifndef _WIN32
129  /** server socket/fifo. */
130  std::string input_path_;
131 #endif
132 
133  std::string uuid_;
134 
135  const std::string config_file_;
137 
138  /** Read the server config from file 'config_file_'. */
139  config read_config() const;
140 
141  // settings from the server config
142  std::vector<std::string> accepted_versions_;
143  std::string recommended_version_;
144  std::map<std::string,config> redirected_versions_;
145  std::map<std::string,config> proxy_versions_;
146  std::vector<std::string> disallowed_names_;
147  std::string admin_passwd_;
148  std::string motd_;
149  std::string announcements_;
150  std::string server_id_;
151  std::string tournaments_;
152  std::string information_;
154  std::size_t default_time_period_;
157  std::time_t lan_server_;
158  std::time_t last_user_seen_time_;
159  std::string restart_command;
160  std::size_t max_ip_log_size_;
163  std::string replay_save_path_;
165  std::set<std::string> client_sources_;
166  std::vector<std::string> tor_ip_list_;
168  std::time_t failed_login_ban_;
169  std::deque<login_log>::size_type failed_login_buffer_size_;
170 
171  /** Parse the server config into local variables. */
172  void load_config();
173 
174  bool ip_exceeds_connection_limit(const std::string& ip) const;
175  std::string is_ip_banned(const std::string& ip);
176 
180 
182 
184 
185  std::deque<std::shared_ptr<game>> games() const
186  {
187  std::deque<std::shared_ptr<game>> result;
188 
189  for(const auto& iter : player_connections_.get<game_t>()) {
190  if(result.empty() || iter.get_game() != result.back()) {
191  result.push_back(iter.get_game());
192  }
193  }
194 
195  if(!result.empty() && result.front() == nullptr) {
196  result.pop_front();
197  }
198 
199  return result;
200  }
201 
202  boost::asio::steady_timer dump_stats_timer_;
203  void start_dump_stats();
204  void dump_stats(const boost::system::error_code& ec);
205 
206  boost::asio::steady_timer tournaments_timer_;
208  void refresh_tournaments(const boost::system::error_code& ec);
209 
210  /** Process commands from admins and users. */
211  std::string process_command(std::string cmd, std::string issuer_name);
212 
213  void delete_game(int, const std::string& reason="");
214 
215  void update_game_in_lobby(const game& g, std::optional<player_iterator> exclude = {});
216 
217  void start_new_server();
218 
219  void setup_fifo();
220 #ifndef _WIN32
221  void handle_read_from_fifo(const boost::system::error_code& error, std::size_t bytes_transferred);
222 #endif
223  void setup_handlers();
224 
225  typedef std::function<void(const std::string&, const std::string&, std::string&, std::ostringstream *)> cmd_handler;
226  std::map<std::string, cmd_handler> cmd_handlers_;
227 
228  void shut_down_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
229  void restart_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
230  void sample_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
231  void help_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
232  void stats_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
233  void metrics_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
234  void requests_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
235  void roll_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
236  void games_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
237  void wml_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
238  void adminmsg_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
239  void pm_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
240  void version_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
241  void msg_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
242  void lobbymsg_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
243  void status_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
244  void clones_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
245  void bans_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
246  void ban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
247  void unban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
248  void ungban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
249  void kick_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
250  void kickban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
251  void gban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
252  void motd_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
253  void searchlog_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
254  void dul_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
255  void stopgame(const std::string &, const std::string &, std::string &, std::ostringstream *);
256 
257 #ifndef _WIN32
258  void handle_sighup(const boost::system::error_code& error, int signal_number);
259 #endif
260 
261  boost::asio::steady_timer timer_;
262  void handle_graceful_timeout(const boost::system::error_code& error);
263 
264  boost::asio::steady_timer lan_server_timer_;
265  void start_lan_server_timer();
266  void abort_lan_server_timer();
267  void handle_lan_server_shutdown(const boost::system::error_code& error);
268 
269  boost::asio::steady_timer dummy_player_timer_;
272  void dummy_player_updates(const boost::system::error_code& ec);
273 };
274 
275 }
std::string motd_
Definition: server.hpp:148
std::set< std::string > client_sources_
Definition: server.hpp:165
void handle_whisper(player_iterator player, simple_wml::node &whisper)
Definition: server.cpp:1144
bool authenticate(SocketPtr socket, const std::string &username, const std::string &password, bool name_taken, bool &registered)
Definition: server.cpp:935
void shut_down_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2068
simple_wml::document games_and_users_list_
Definition: server.hpp:179
std::deque< login_log >::size_type failed_login_buffer_size_
Definition: server.hpp:169
std::string uuid_
Definition: server.hpp:133
void send_to_lobby(simple_wml::document &data, std::optional< player_iterator > exclude={})
Definition: server.cpp:1968
void status_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2407
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
void games_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2236
void refresh_tournaments(const boost::system::error_code &ec)
Definition: server.cpp:660
std::string tournaments_
Definition: server.hpp:151
void remove_player(player_iterator player)
Definition: server.cpp:1924
int failed_login_limit_
Definition: server.hpp:167
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:40
bool save_replays_
Definition: server.hpp:162
std::function< void(const std::string &, const std::string &, std::string &, std::ostringstream *)> cmd_handler
Definition: server.hpp:225
void kickban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2571
void start_dump_stats()
Definition: server.cpp:593
void start_lan_server_timer()
Definition: server.cpp:304
std::string announcements_
Definition: server.hpp:149
std::unique_ptr< user_handler > user_handler_
Definition: server.hpp:124
bool accepting_connections() const
Definition: server.hpp:55
void help_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2155
void send_server_message(player_iterator player, const std::string &message, const std::string &type)
Definition: server.hpp:72
void wml_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2245
void stats_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2164
void handle_read_from_fifo(const boost::system::error_code &error, std::size_t bytes_transferred)
Definition: server.cpp:340
void handle_message(player_iterator player, simple_wml::node &message)
Definition: server.cpp:1289
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:110
std::size_t default_time_period_
Definition: server.hpp:154
void handle_join_game(player_iterator player, simple_wml::node &join)
Definition: server.cpp:1392
void requests_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2184
Base class for implementing servers that use gzipped-WML network protocol.
Definition: server_base.hpp:78
std::vector< std::string > accepted_versions_
Definition: server.hpp:142
std::size_t default_max_messages_
Definition: server.hpp:153
void ban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2508
std::string information_
Definition: server.hpp:152
Definitions for the interface to Wesnoth Markup Language (WML).
void handle_sighup(const boost::system::error_code &error, int signal_number)
Definition: server.cpp:278
player_connections::const_iterator player_iterator
bool deny_unregistered_login_
Definition: server.hpp:161
void handle_graceful_timeout(const boost::system::error_code &error)
Definition: server.cpp:291
void gban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2647
bool operator==(const connection_log &c) const
Definition: server.hpp:100
std::string recommended_version_
Definition: server.hpp:143
void start_tournaments_timer()
Definition: server.cpp:654
simple_wml::document login_response_
Definition: server.hpp:178
bmi::multi_index_container< player_record, bmi::indexed_by< bmi::ordered_unique< bmi::tag< socket_t >, bmi::const_mem_fun< player_record, const any_socket_ptr, &player_record::socket > >, bmi::hashed_unique< bmi::tag< name_t >, bmi::const_mem_fun< player_record, const std::string &, &player_record::name > >, bmi::ordered_non_unique< bmi::tag< game_t >, bmi::const_mem_fun< player_record, int, &player_record::game_id > > > > player_connections
bool allow_remote_shutdown_
Definition: server.hpp:164
std::map< std::string, config > proxy_versions_
Definition: server.hpp:145
std::mt19937 die_
Definition: server.hpp:126
void msg_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2342
void handle_lan_server_shutdown(const boost::system::error_code &error)
Definition: server.cpp:315
std::string restart_command
Definition: server.hpp:159
void handle_player_in_game(player_iterator player, simple_wml::document &doc)
Definition: server.cpp:1470
int dummy_player_timer_interval_
Definition: server.hpp:270
void handle_player(boost::asio::yield_context yield, SocketPtr socket, const player &player)
Definition: server.cpp:1061
bool player_is_in_game(player_iterator player) const
Definition: server.hpp:88
boost::asio::steady_timer timer_
Definition: server.hpp:261
void async_send_doc_queued(SocketPtr socket, simple_wml::document &doc)
High level wrapper for sending a WML document.
void clones_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2449
bool ip_exceeds_connection_limit(const std::string &ip) const
Definition: server.cpp:566
std::string input_path_
server socket/fifo.
Definition: server.hpp:130
void send_server_message_to_all(const std::string &message, std::optional< player_iterator > exclude={})
Definition: server.cpp:1988
void motd_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2793
std::vector< std::string > tor_ip_list_
Definition: server.hpp:166
void bans_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2483
void searchlog_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2814
simple_wml::document version_query_response_
Definition: server.hpp:177
std::string replay_save_path_
Definition: server.hpp:163
void kick_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2742
boost::asio::steady_timer dump_stats_timer_
Definition: server.hpp:202
std::string login()
std::string server_id_
Definition: server.hpp:150
void cleanup_game(game *)
Definition: server.cpp:1360
void send_to_player(player_iterator player, simple_wml::document &data)
Definition: server.hpp:79
bool graceful_restart
Definition: server.hpp:156
void sample_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2134
void start_new_server()
Definition: server.cpp:1997
boost::asio::steady_timer lan_server_timer_
Definition: server.hpp:264
std::size_t concurrent_connections_
Definition: server.hpp:155
void unban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2712
const std::string config_file_
Definition: server.hpp:135
void roll_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2193
void delete_game(int, const std::string &reason="")
Definition: server.cpp:2910
double g
Definition: astarsearch.cpp:65
std::time_t failed_login_ban_
Definition: server.hpp:168
std::string password(const std::string &server, const std::string &login)
std::string admin_passwd_
Definition: server.hpp:147
wesnothd::ban_manager ban_manager_
Definition: server.hpp:93
std::deque< login_log > failed_logins_
Definition: server.hpp:122
void adminmsg_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2254
boost::asio::steady_timer tournaments_timer_
Definition: server.hpp:206
void stopgame(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2888
metrics metrics_
Definition: server.hpp:181
bool operator==(const login_log &l) const
Definition: server.hpp:115
std::map< std::string, config > redirected_versions_
Definition: server.hpp:144
void handle_query(player_iterator player, simple_wml::node &query)
Definition: server.cpp:1184
boost::asio::steady_timer dummy_player_timer_
Definition: server.hpp:269
void dump_stats(const boost::system::error_code &ec)
Definition: server.cpp:599
bool is_login_allowed(SocketPtr socket, const simple_wml::node *const login, const std::string &username, bool &registered, bool &is_moderator)
Definition: server.cpp:815
void restart_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2099
void dummy_player_updates(const boost::system::error_code &ec)
Definition: server.cpp:617
void version_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2387
std::string is_ip_banned(const std::string &ip)
Definition: server.cpp:582
std::time_t lan_server_
Definition: server.hpp:157
void login_client(boost::asio::yield_context yield, SocketPtr socket)
Definition: server.cpp:683
void start_dummy_player_updates()
Definition: server.cpp:611
server(int port, bool keep_alive, const std::string &config_file, std::size_t, std::size_t)
Definition: server.cpp:211
void handle_create_game(player_iterator player, simple_wml::node &create_game)
Definition: server.cpp:1316
std::shared_ptr< boost::asio::ssl::stream< socket_ptr::element_type > > tls_socket_ptr
Definition: server_base.hpp:51
void setup_handlers()
Definition: server.cpp:369
std::map< std::string, cmd_handler > cmd_handlers_
Definition: server.hpp:226
void setup_fifo()
Definition: server.cpp:323
void dul_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2867
std::shared_ptr< boost::asio::ip::tcp::socket > socket_ptr
Definition: server_base.hpp:48
player_connections player_connections_
Definition: server.hpp:183
void load_config()
Parse the server config into local variables.
Definition: server.cpp:431
std::deque< std::shared_ptr< game > > games() const
Definition: server.hpp:185
void update_game_in_lobby(const game &g, std::optional< player_iterator > exclude={})
Definition: server.cpp:2954
std::deque< connection_log > ip_log_
Definition: server.hpp:107
void handle_new_client(socket_ptr socket)
Definition: server.cpp:672
void ungban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2727
std::string process_command(std::string cmd, std::string issuer_name)
Process commands from admins and users.
Definition: server.cpp:2013
config read_config() const
Read the server config from file &#39;config_file_&#39;.
Definition: server.cpp:412
void metrics_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2175
void send_server_message(SocketPtr socket, const std::string &message, const std::string &type)
Definition: server.cpp:1902
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:61
void lobbymsg_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2365
void pm_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2300
mock_char c
void handle_player_in_lobby(player_iterator player, simple_wml::document &doc)
Definition: server.cpp:1126
void abort_lan_server_timer()
Definition: server.cpp:310
std::size_t max_ip_log_size_
Definition: server.hpp:160
void disconnect_player(player_iterator player)
Definition: server.cpp:1913
void handle_nickserv(player_iterator player, simple_wml::node &nickserv)
Definition: server.cpp:1264
void send_server_message_to_lobby(const std::string &message, std::optional< player_iterator > exclude={})
Definition: server.cpp:1978
std::time_t last_user_seen_time_
Definition: server.hpp:158
std::vector< std::string > disallowed_names_
Definition: server.hpp:146
Base class for servers using Wesnoth&#39;s WML over TCP protocol.
void send_password_request(SocketPtr socket, const std::string &msg, const char *error_code="", bool force_confirmation=false)
Definition: server.cpp:1043