added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / sync / server.hpp
1 /*************************************************************************
2  *
3  * REALM CONFIDENTIAL
4  * __________________
5  *
6  *  [2011] - [2012] Realm Inc
7  *  All Rights Reserved.
8  *
9  * NOTICE:  All information contained herein is, and remains
10  * the property of Realm Incorporated and its suppliers,
11  * if any.  The intellectual and technical concepts contained
12  * herein are proprietary to Realm Incorporated
13  * and its suppliers and may be covered by U.S. and Foreign Patents,
14  * patents in process, and are protected by trade secret or copyright law.
15  * Dissemination of this information or reproduction of this material
16  * is strictly forbidden unless prior written permission is obtained
17  * from Realm Incorporated.
18  *
19  **************************************************************************/
20 #ifndef REALM_SYNC_SERVER_HPP
21 #define REALM_SYNC_SERVER_HPP
22
23 #include <stdint.h>
24 #include <memory>
25 #include <string>
26
27 #include <realm/util/network.hpp>
28 #include <realm/util/logger.hpp>
29 #include <realm/util/optional.hpp>
30 #include <realm/sync/crypto_server.hpp>
31 #include <realm/sync/metrics.hpp>
32
33 namespace realm {
34 namespace sync {
35
36 class Server {
37 public:
38     class TokenExpirationClock;
39
40     struct Config {
41         Config() {}
42
43         /// The maximum number of Realm files that will be kept open
44         /// concurrently by this server. The server keeps a cache of open Realm
45         /// files for efficiency reasons.
46         long max_open_files = 256;
47
48         /// An optional custom clock to be used for token expiration checks. If
49         /// no clock is specified, the server will use the system clock.
50         TokenExpirationClock* token_expiration_clock = nullptr;
51
52         /// An optional logger to be used by the server. If no logger is
53         /// specified, the server will use an instance of util::StderrLogger
54         /// with the log level threshold set to util::Logger::Level::info. The
55         /// server does not require a thread-safe logger, and it guarantees that
56         /// all logging happens on behalf of start() and run() (which are not
57         /// allowed to execute concurrently).
58         util::Logger* logger = nullptr;
59
60         /// An optional sink for recording metrics about the internal operation
61         /// of the server. For the list of counters and gauges see
62         /// "doc/monitoring.md".
63         Metrics* metrics = nullptr;
64
65         /// A unique id of this server. Used in the backup protocol to tell
66         /// slaves apart.
67         std::string id = "unknown";
68
69         /// The address at which the listening socket is bound.
70         /// The address can be a name or on numerical form.
71         /// Use "localhost" to listen on the loopback interface.
72         std::string listen_address;
73
74         /// The port at which the listening socket is bound.
75         /// The port can be a name or on numerical form.
76         /// Use the empty string to have the system assign a dynamic
77         /// listening port.
78         std::string listen_port;
79
80         bool reuse_address = true;
81
82         /// The listening socket accepts TLS/SSL connections if `ssl` is
83         /// true, and non-secure tcp connections otherwise.
84         bool ssl = false;
85
86         /// The path of the certificate that will be sent to clients during
87         /// the SSL/TLS handshake.
88         ///
89         /// From the point of view of OpenSSL, this file will be passed to
90         /// `SSL_CTX_use_certificate_chain_file()`.
91         ///
92         /// This option is ignore if `ssl` is false.
93         std::string ssl_certificate_path;
94
95         /// The path of the private key corresponding to the certificate.
96         ///
97         /// From the point of view of OpenSSL, this file will be passed to
98         /// `SSL_CTX_use_PrivateKey_file()`.
99         ///
100         /// This option is ignore if `ssl` is false.
101         std::string ssl_certificate_key_path;
102
103         // A connection which has not been sending any messages or pings for
104         // `idle_timeout_ms` is considered dead and will be dropped by the server.
105         uint_fast64_t idle_timeout_ms = 1800000; // 30 minutes
106
107         // How often the server scans through the connection list to drop idle ones.
108         uint_fast64_t drop_period_ms = 60000; // 1 minute
109
110         /// @{ \brief The operating mode of the Sync worker.
111         ///
112         /// MasterWithNoSlave is a standard Sync worker without backup.
113         /// If a backup slave attempts to contact a MasterNoBackup server,
114         /// the slave will be rejected.
115         ///
116         /// MasterWithAsynchronousSlave represents a Sync worker that operates
117         /// independently of a backup slave. If a slave connects to the
118         /// MasterAsynchronousSlave server, the server will accept the connection
119         /// and send backup information to the slave. This type of master server
120         /// will never wait for the slave, however.
121         ///
122         /// MasterWithSynchronousSlave represents a Sync worker that works in
123         /// coordination with a slave. The master will send all updates to the
124         /// slave and wait for acknowledgment before the master sends its own
125         /// acknowledgment to the clients. This mode of operation is the safest
126         /// type of backup, but it generally will have higher latency than the previous
127         /// two types of server.
128         ///
129         /// Slave represents a backup server. A slave is used to backup a master.
130         /// The slave connects to the master and reconnects in case a network fallout.
131         /// The slave receives updates from the master and acknowledges them.
132         /// A slave rejects all connections from Sync clients.
133         enum class OperatingMode {
134             MasterWithNoSlave,
135             MasterWithAsynchronousSlave,
136             MasterWithSynchronousSlave,
137             Slave
138         };
139         OperatingMode operating_mode = OperatingMode::MasterWithNoSlave;
140         /// @}
141
142         /// @{ \brief Adress of master sync work.
143         ///
144         /// master_address and master_port are only meaningful in Slave mode.
145         /// The parameters represent the address of the master from which this
146         /// slave obtains Realm updates.
147         std::string master_address;
148         std::string master_port;
149         /// @}
150
151         /// @{ \brief SSL for master slave communication.
152         ///
153         /// The master and slave communicate over a SSL connection if
154         /// master_slave_ssl is set to true(default = false). The certificate of the
155         /// master is verified if master_verify_ssl_certificate is set to true.
156         /// The certificate verification attempts to use the default trust store of the
157         /// instance if master_ssl_trust_certificate_path is none(default), otherwise
158         /// the certificate at the master_ssl_trust_certificate_path is used for
159         /// verification.
160         bool master_slave_ssl = false;
161         bool master_verify_ssl_certificate = true;
162         util::Optional<std::string> master_ssl_trust_certificate_path = util::none;
163         /// @}
164
165         /// A master Sync server will only accept a backup connection from a slave
166         /// that can present the correct master_slave_shared_secret.
167         /// The configuration of the master and the slave must contain the same
168         /// secret string.
169         /// The secret is sent in a HTTP header and must be a valid HTTP header value.
170         std::string master_slave_shared_secret = "replace-this-string-with-a-secret";
171
172         /// A callback which gets called by the backup master every time the slave
173         /// changes its status to up-to-date or back. The arguments carry the
174         /// slave's id (string) and its up-to-dateness state (bool).
175         std::function<void(std::string, bool)> slave_status_callback;
176
177         /// The feature token is used by the server to gate access to various
178         /// features.
179         util::Optional<std::string> feature_token;
180
181         /// The server can try to eliminate redundant instructions from
182         /// changesets before sending them to clients, minimizing download sizes
183         /// at the expense of server CPU usage.
184         bool enable_download_log_compaction = true;
185
186         /// The accumulated size of changesets that are included in download
187         /// messages. The size of the changesets is calculated before log
188         /// compaction (if enabled). A larger value leads to more efficient
189         /// log compaction and download, at the expense of higher memory pressure,
190         /// higher latency for sending the first changeset, and a higher probability
191         /// for the need to resend the same changes after network disconnects.
192         size_t max_download_size = 0x20000; // 128 KiB
193
194         /// Set the `TCP_NODELAY` option on all TCP/IP sockets. This disables
195         /// the Nagle algorithm. Disabling it, can in some cases be used to
196         /// decrease latencies, but possibly at the expense of scalability. Be
197         /// sure to research the subject before you enable this option.
198         bool tcp_no_delay = false;
199     };
200
201     Server(const std::string& root_dir, util::Optional<PKey> public_key, Config = {});
202     Server(Server&&) noexcept;
203     ~Server() noexcept;
204
205     /// start() binds a listening socket to the address and port specified in
206     /// Config and starts accepting connections.
207     /// The resolved endpoint (including the dynamically assigned port, if requested)
208     /// can be obtained by calling listen_endpoint().
209     /// This can be done immediately after start() returns.
210     void start();
211
212     /// A helper function, for backwards compatibility, that starts a listening
213     /// socket without SSL at the specified address and port.
214     void start(const std::string& listen_address,
215                const std::string& listen_port,
216                bool reuse_address = true);
217
218     /// Return the resolved and bound endpoint of the listening socket.
219     util::network::Endpoint listen_endpoint() const;
220
221     /// Run the internal event-loop of the server. At most one thread may
222     /// execute run() at any given time. It is an error if run() is called
223     /// before start() has been successfully executed. The call to run() will
224     /// not return until somebody calls stop().
225     void run();
226
227     /// Stop any thread that is currently executing run(). This function may be
228     /// called by any thread.
229     void stop() noexcept;
230
231     /// Must not be called while run() is executing.
232     uint_fast64_t errors_seen() const noexcept;
233
234     /// A connection which has not been sending any messages or pings for
235     /// `idle_timeout_ms` is considered idle and will be dropped by the server.
236     void set_idle_timeout_ms(uint_fast64_t idle_timeout_ms);
237
238     /// Close all connections with error code ProtocolError::connection_closed.
239     ///
240     /// This function exists mainly for debugging purposes.
241     void close_connections();
242
243 private:
244     class Implementation;
245     std::unique_ptr<Implementation> m_impl;
246 };
247
248
249 class Server::TokenExpirationClock {
250 public:
251     /// Number of seconds since the Epoch. The Epoch is the epoch of
252     /// std::chrono::system_clock.
253     virtual std::int_fast64_t now() noexcept = 0;
254
255     virtual ~TokenExpirationClock() {}
256 };
257
258 } // namespace sync
259 } // namespace realm
260
261 #endif // REALM_SYNC_SERVER_HPP