1 //
2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #pragma once
8 
9 #include "td/telegram/net/DcId.h"
10 #include "td/telegram/net/NetQuery.h"
11 
12 #include "td/actor/actor.h"
13 #include "td/actor/PromiseFuture.h"
14 
15 #include "td/utils/common.h"
16 #include "td/utils/ScopeGuard.h"
17 #include "td/utils/Status.h"
18 
19 #include <array>
20 #include <atomic>
21 #include <functional>
22 #include <memory>
23 #include <mutex>
24 
25 namespace td {
26 
27 class DcAuthManager;
28 class NetQueryDelayer;
29 class PublicRsaKeyShared;
30 class PublicRsaKeyWatchdog;
31 class SessionMultiProxy;
32 
33 // Not just dispatcher.
34 class NetQueryDispatcher {
35  public:
36   explicit NetQueryDispatcher(const std::function<ActorShared<>()> &create_reference);
37   NetQueryDispatcher();
38   NetQueryDispatcher(const NetQueryDispatcher &) = delete;
39   NetQueryDispatcher &operator=(const NetQueryDispatcher &) = delete;
40   NetQueryDispatcher(NetQueryDispatcher &&) = delete;
41   NetQueryDispatcher &operator=(NetQueryDispatcher &&) = delete;
42   ~NetQueryDispatcher();
43 
44   void dispatch(NetQueryPtr net_query);
45   void dispatch_with_callback(NetQueryPtr net_query, ActorShared<NetQueryCallback> callback);
46   void stop();
47 
48   void update_session_count();
49   void destroy_auth_keys(Promise<> promise);
50   void update_use_pfs();
51   void update_mtproto_header();
52 
53   void update_valid_dc(DcId dc_id);
54 
get_main_dc_id()55   DcId get_main_dc_id() const {
56     return DcId::internal(main_dc_id_.load(std::memory_order_relaxed));
57   }
58 
59   void set_main_dc_id(int32 new_main_dc_id);
60 
61  private:
62   std::atomic<bool> stop_flag_{false};
63   bool need_destroy_auth_key_{false};
64   ActorOwn<NetQueryDelayer> delayer_;
65   ActorOwn<DcAuthManager> dc_auth_manager_;
66   struct Dc {
67     DcId id_;
68     std::atomic<bool> is_valid_{false};
69     std::atomic<bool> is_inited_{false};  // TODO: cache in scheduler local storage :D
70 
71     ActorOwn<SessionMultiProxy> main_session_;
72     ActorOwn<SessionMultiProxy> download_session_;
73     ActorOwn<SessionMultiProxy> download_small_session_;
74     ActorOwn<SessionMultiProxy> upload_session_;
75   };
76   static constexpr size_t MAX_DC_COUNT = 1000;
77   std::array<Dc, MAX_DC_COUNT> dcs_;
78 #if TD_EMSCRIPTEN  // FIXME
79   std::atomic<int32> main_dc_id_{2};
80 #else
81   std::atomic<int32> main_dc_id_{1};
82 #endif
83   std::shared_ptr<PublicRsaKeyShared> common_public_rsa_key_;
84   ActorOwn<PublicRsaKeyWatchdog> public_rsa_key_watchdog_;
85   std::mutex main_dc_id_mutex_;
86   std::shared_ptr<Guard> td_guard_;
87 
88   Status wait_dc_init(DcId dc_id, bool force);
89   bool is_dc_inited(int32 raw_dc_id);
90 
91   static int32 get_session_count();
92   static bool get_use_pfs();
93 
94   static void complete_net_query(NetQueryPtr net_query);
95 
96   void try_fix_migrate(NetQueryPtr &net_query);
97 };
98 
99 }  // namespace td
100