The Battle for Wesnoth  1.17.0-dev
server.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2018 by David White <dave@whitevine.net>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License 2
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
17 #include "config.hpp"
20 #include "server/wesnothd/ban.hpp"
25 
26 #include <boost/asio/steady_timer.hpp>
27 
28 #include <optional>
29 #include <random>
30 
31 namespace wesnothd
32 {
33 
34 class server : public server_base
35 {
36 public:
37  server(int port, bool keep_alive, const std::string& config_file, std::size_t, std::size_t);
38 
39 private:
40  void handle_new_client(socket_ptr socket);
41  void handle_new_client(tls_socket_ptr socket);
42 
43  template<class SocketPtr> void login_client(boost::asio::yield_context yield, SocketPtr socket);
44  template<class SocketPtr> bool is_login_allowed(SocketPtr socket, const simple_wml::node* const login, const std::string& username, bool& registered, bool& is_moderator);
45  template<class SocketPtr> bool authenticate(SocketPtr socket, const std::string& username, const std::string& password, bool name_taken, bool& registered);
46  template<class SocketPtr> void send_password_request(SocketPtr socket, const std::string& msg, const char* error_code = "", bool force_confirmation = false);
47  bool accepting_connections() const { return !graceful_restart; }
48 
49  template<class SocketPtr> void handle_player(boost::asio::yield_context yield, SocketPtr socket, const player& player);
52  void handle_whisper(player_iterator player, simple_wml::node& whisper);
53  void handle_query(player_iterator player, simple_wml::node& query);
54  void handle_nickserv(player_iterator player, simple_wml::node& nickserv);
55  void handle_message(player_iterator player, simple_wml::node& message);
56  void handle_create_game(player_iterator player, simple_wml::node& create_game);
57  void cleanup_game(game*); // deleter for shared_ptr
60  void remove_player(player_iterator player);
61 
62 public:
63  template<class SocketPtr> void send_server_message(SocketPtr socket, const std::string& message, const std::string& type);
64  void send_server_message(player_iterator player, const std::string& message, const std::string& type) {
65  utils::visit(
66  [this, &message, &type](auto&& socket) { send_server_message(socket, message, type); },
67  player->socket()
68  );
69  }
70  void send_to_lobby(simple_wml::document& data, std::optional<player_iterator> exclude = {});
72  utils::visit(
73  [this, &data](auto&& socket) { async_send_doc_queued(socket, data); },
74  player->socket()
75  );
76  }
77  void send_server_message_to_lobby(const std::string& message, std::optional<player_iterator> exclude = {});
78  void send_server_message_to_all(const std::string& message, std::optional<player_iterator> exclude = {});
79 
80  bool player_is_in_game(player_iterator player) const {
81  return player->get_game() != nullptr;
82  }
83 
84 private:
86 
88  {
89  std::string nick, ip;
90  std::time_t log_off;
91 
92  bool operator==(const connection_log& c) const
93  {
94  // log off time does not matter to find ip-nick pairs
95  return c.nick == nick && c.ip == ip;
96  }
97  };
98 
99  std::deque<connection_log> ip_log_;
100 
101  struct login_log
102  {
103  std::string ip;
104  int attempts;
105  std::time_t first_attempt;
106 
107  bool operator==(const login_log& l) const
108  {
109  // only the IP matters
110  return l.ip == ip;
111  }
112  };
113 
114  std::deque<login_log> failed_logins_;
115 
116  std::unique_ptr<user_handler> user_handler_;
117 
118  std::mt19937 die_;
119 
121 
122  std::deque<std::shared_ptr<game>> games() const
123  {
124  std::deque<std::shared_ptr<game>> result;
125 
126  for(const auto& iter : player_connections_.get<game_t>()) {
127  if(result.empty() || iter.get_game() != result.back()) {
128  result.push_back(iter.get_game());
129  }
130  }
131 
132  if(!result.empty() && result.front() == nullptr) {
133  result.pop_front();
134  }
135 
136  return result;
137  }
138 
139 #ifndef _WIN32
140  /** server socket/fifo. */
141  std::string input_path_;
142 #endif
143 
144  std::string uuid_;
145 
146  const std::string config_file_;
148 
149  /** Read the server config from file 'config_file_'. */
150  config read_config() const;
151 
152  // settings from the server config
153  std::vector<std::string> accepted_versions_;
154  std::string recommended_version_;
155  std::map<std::string,config> redirected_versions_;
156  std::map<std::string,config> proxy_versions_;
157  std::vector<std::string> disallowed_names_;
158  std::string admin_passwd_;
159  std::string motd_;
160  std::string announcements_;
161  std::string server_id_;
162  std::string tournaments_;
163  std::string information_;
165  std::size_t default_time_period_;
168  std::time_t lan_server_;
169  std::time_t last_user_seen_time_;
170  std::string restart_command;
171  std::size_t max_ip_log_size_;
174  std::string replay_save_path_;
176  std::set<std::string> client_sources_;
177  std::vector<std::string> tor_ip_list_;
179  std::time_t failed_login_ban_;
180  std::deque<login_log>::size_type failed_login_buffer_size_;
181 
182  /** Parse the server config into local variables. */
183  void load_config();
184 
185  bool ip_exceeds_connection_limit(const std::string& ip) const;
186  std::string is_ip_banned(const std::string& ip);
187 
191 
193 
194  boost::asio::steady_timer dump_stats_timer_;
195  void start_dump_stats();
196  void dump_stats(const boost::system::error_code& ec);
197 
198  boost::asio::steady_timer tournaments_timer_;
200  void refresh_tournaments(const boost::system::error_code& ec);
201 
202  /** Process commands from admins and users. */
203  std::string process_command(std::string cmd, std::string issuer_name);
204 
205  void delete_game(int, const std::string& reason="");
206 
207  void update_game_in_lobby(const game& g, std::optional<player_iterator> exclude = {});
208 
209  void start_new_server();
210 
211  void setup_fifo();
212 #ifndef _WIN32
213  void handle_read_from_fifo(const boost::system::error_code& error, std::size_t bytes_transferred);
214 #endif
215  void setup_handlers();
216 
217  typedef std::function<void(const std::string&, const std::string&, std::string&, std::ostringstream *)> cmd_handler;
218  std::map<std::string, cmd_handler> cmd_handlers_;
219 
220  void shut_down_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
221  void restart_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
222  void sample_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
223  void help_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
224  void stats_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
225  void metrics_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
226  void requests_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
227  void roll_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
228  void games_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
229  void wml_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
230  void adminmsg_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
231  void pm_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
232  void version_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
233  void msg_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
234  void lobbymsg_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
235  void status_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
236  void clones_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
237  void bans_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
238  void ban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
239  void unban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
240  void ungban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
241  void kick_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
242  void kickban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
243  void gban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
244  void motd_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
245  void searchlog_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
246  void dul_handler(const std::string &, const std::string &, std::string &, std::ostringstream *);
247  void stopgame(const std::string &, const std::string &, std::string &, std::ostringstream *);
248 
249 #ifndef _WIN32
250  void handle_sighup(const boost::system::error_code& error, int signal_number);
251 #endif
252 
253  boost::asio::steady_timer timer_;
254  void handle_graceful_timeout(const boost::system::error_code& error);
255 
256  boost::asio::steady_timer lan_server_timer_;
257  void start_lan_server_timer();
258  void abort_lan_server_timer();
259  void handle_lan_server_shutdown(const boost::system::error_code& error);
260 
261  boost::asio::steady_timer dummy_player_timer_;
264  void dummy_player_updates(const boost::system::error_code& ec);
265 };
266 
267 }
std::string motd_
Definition: server.hpp:159
std::set< std::string > client_sources_
Definition: server.hpp:176
void handle_whisper(player_iterator player, simple_wml::node &whisper)
Definition: server.cpp:1140
bool authenticate(SocketPtr socket, const std::string &username, const std::string &password, bool name_taken, bool &registered)
Definition: server.cpp:933
void shut_down_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2064
simple_wml::document games_and_users_list_
Definition: server.hpp:190
std::deque< login_log >::size_type failed_login_buffer_size_
Definition: server.hpp:180
std::string uuid_
Definition: server.hpp:144
void send_to_lobby(simple_wml::document &data, std::optional< player_iterator > exclude={})
Definition: server.cpp:1964
void status_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2403
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:2232
void refresh_tournaments(const boost::system::error_code &ec)
Definition: server.cpp:658
std::string tournaments_
Definition: server.hpp:162
void remove_player(player_iterator player)
Definition: server.cpp:1920
int failed_login_limit_
Definition: server.hpp:178
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:40
bool save_replays_
Definition: server.hpp:173
std::function< void(const std::string &, const std::string &, std::string &, std::ostringstream *)> cmd_handler
Definition: server.hpp:217
void kickban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2567
void start_dump_stats()
Definition: server.cpp:591
void start_lan_server_timer()
Definition: server.cpp:302
std::string announcements_
Definition: server.hpp:160
std::unique_ptr< user_handler > user_handler_
Definition: server.hpp:116
bool accepting_connections() const
Definition: server.hpp:47
void help_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2151
void send_server_message(player_iterator player, const std::string &message, const std::string &type)
Definition: server.hpp:64
void wml_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2241
void stats_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2160
void handle_read_from_fifo(const boost::system::error_code &error, std::size_t bytes_transferred)
Definition: server.cpp:338
void handle_message(player_iterator player, simple_wml::node &message)
Definition: server.cpp:1285
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
std::size_t default_time_period_
Definition: server.hpp:165
void handle_join_game(player_iterator player, simple_wml::node &join)
Definition: server.cpp:1388
void requests_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2180
Base class for implementing servers that use gzipped-WML network protocol.
Definition: server_base.hpp:77
std::vector< std::string > accepted_versions_
Definition: server.hpp:153
std::size_t default_max_messages_
Definition: server.hpp:164
void ban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2504
std::string information_
Definition: server.hpp:163
Definitions for the interface to Wesnoth Markup Language (WML).
void handle_sighup(const boost::system::error_code &error, int signal_number)
Definition: server.cpp:276
player_connections::const_iterator player_iterator
bool deny_unregistered_login_
Definition: server.hpp:172
void handle_graceful_timeout(const boost::system::error_code &error)
Definition: server.cpp:289
void gban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2643
bool operator==(const connection_log &c) const
Definition: server.hpp:92
std::string recommended_version_
Definition: server.hpp:154
void start_tournaments_timer()
Definition: server.cpp:652
simple_wml::document login_response_
Definition: server.hpp:189
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:175
std::map< std::string, config > proxy_versions_
Definition: server.hpp:156
std::mt19937 die_
Definition: server.hpp:118
void msg_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2338
void handle_lan_server_shutdown(const boost::system::error_code &error)
Definition: server.cpp:313
std::string restart_command
Definition: server.hpp:170
void handle_player_in_game(player_iterator player, simple_wml::document &doc)
Definition: server.cpp:1466
int dummy_player_timer_interval_
Definition: server.hpp:262
void handle_player(boost::asio::yield_context yield, SocketPtr socket, const player &player)
Definition: server.cpp:1059
bool player_is_in_game(player_iterator player) const
Definition: server.hpp:80
boost::asio::steady_timer timer_
Definition: server.hpp:253
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:2445
bool ip_exceeds_connection_limit(const std::string &ip) const
Definition: server.cpp:564
std::string input_path_
server socket/fifo.
Definition: server.hpp:141
void send_server_message_to_all(const std::string &message, std::optional< player_iterator > exclude={})
Definition: server.cpp:1984
void motd_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2789
std::vector< std::string > tor_ip_list_
Definition: server.hpp:177
void bans_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2479
void searchlog_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2810
simple_wml::document version_query_response_
Definition: server.hpp:188
std::string replay_save_path_
Definition: server.hpp:174
void kick_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2738
boost::asio::steady_timer dump_stats_timer_
Definition: server.hpp:194
std::string login()
std::string server_id_
Definition: server.hpp:161
void cleanup_game(game *)
Definition: server.cpp:1356
void send_to_player(player_iterator player, simple_wml::document &data)
Definition: server.hpp:71
bool graceful_restart
Definition: server.hpp:167
void sample_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2130
void start_new_server()
Definition: server.cpp:1993
boost::asio::steady_timer lan_server_timer_
Definition: server.hpp:256
std::size_t concurrent_connections_
Definition: server.hpp:166
void unban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2708
const std::string config_file_
Definition: server.hpp:146
void roll_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2189
void delete_game(int, const std::string &reason="")
Definition: server.cpp:2906
double g
Definition: astarsearch.cpp:64
std::time_t failed_login_ban_
Definition: server.hpp:179
std::string password(const std::string &server, const std::string &login)
std::string admin_passwd_
Definition: server.hpp:158
wesnothd::ban_manager ban_manager_
Definition: server.hpp:85
std::deque< login_log > failed_logins_
Definition: server.hpp:114
void adminmsg_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2250
boost::asio::steady_timer tournaments_timer_
Definition: server.hpp:198
void stopgame(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2884
metrics metrics_
Definition: server.hpp:192
bool operator==(const login_log &l) const
Definition: server.hpp:107
std::map< std::string, config > redirected_versions_
Definition: server.hpp:155
void handle_query(player_iterator player, simple_wml::node &query)
Definition: server.cpp:1180
boost::asio::steady_timer dummy_player_timer_
Definition: server.hpp:261
void dump_stats(const boost::system::error_code &ec)
Definition: server.cpp:597
bool is_login_allowed(SocketPtr socket, const simple_wml::node *const login, const std::string &username, bool &registered, bool &is_moderator)
Definition: server.cpp:813
void restart_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2095
void dummy_player_updates(const boost::system::error_code &ec)
Definition: server.cpp:615
void version_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2383
std::string is_ip_banned(const std::string &ip)
Definition: server.cpp:580
std::time_t lan_server_
Definition: server.hpp:168
void login_client(boost::asio::yield_context yield, SocketPtr socket)
Definition: server.cpp:681
void start_dummy_player_updates()
Definition: server.cpp:609
server(int port, bool keep_alive, const std::string &config_file, std::size_t, std::size_t)
Definition: server.cpp:209
void handle_create_game(player_iterator player, simple_wml::node &create_game)
Definition: server.cpp:1312
std::shared_ptr< boost::asio::ssl::stream< socket_ptr::element_type > > tls_socket_ptr
Definition: server_base.hpp:50
void setup_handlers()
Definition: server.cpp:367
std::map< std::string, cmd_handler > cmd_handlers_
Definition: server.hpp:218
void setup_fifo()
Definition: server.cpp:321
void dul_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2863
std::shared_ptr< boost::asio::ip::tcp::socket > socket_ptr
Definition: server_base.hpp:47
player_connections player_connections_
Definition: server.hpp:120
void load_config()
Parse the server config into local variables.
Definition: server.cpp:429
std::deque< std::shared_ptr< game > > games() const
Definition: server.hpp:122
void update_game_in_lobby(const game &g, std::optional< player_iterator > exclude={})
Definition: server.cpp:2950
std::deque< connection_log > ip_log_
Definition: server.hpp:99
void handle_new_client(socket_ptr socket)
Definition: server.cpp:670
void ungban_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2723
std::string process_command(std::string cmd, std::string issuer_name)
Process commands from admins and users.
Definition: server.cpp:2009
config read_config() const
Read the server config from file &#39;config_file_&#39;.
Definition: server.cpp:410
void metrics_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2171
void send_server_message(SocketPtr socket, const std::string &message, const std::string &type)
Definition: server.cpp:1898
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:59
void lobbymsg_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2361
void pm_handler(const std::string &, const std::string &, std::string &, std::ostringstream *)
Definition: server.cpp:2296
mock_char c
void handle_player_in_lobby(player_iterator player, simple_wml::document &doc)
Definition: server.cpp:1122
void abort_lan_server_timer()
Definition: server.cpp:308
std::size_t max_ip_log_size_
Definition: server.hpp:171
void disconnect_player(player_iterator player)
Definition: server.cpp:1909
void handle_nickserv(player_iterator player, simple_wml::node &nickserv)
Definition: server.cpp:1260
void send_server_message_to_lobby(const std::string &message, std::optional< player_iterator > exclude={})
Definition: server.cpp:1974
std::time_t last_user_seen_time_
Definition: server.hpp:169
std::vector< std::string > disallowed_names_
Definition: server.hpp:157
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:1041