1 #ifndef PICHI_API_ROUTER_HPP
2 #define PICHI_API_ROUTER_HPP
3 
4 #include <map>
5 #include <memory>
6 #include <pichi/vo/iterator.hpp>
7 #include <pichi/vo/route.hpp>
8 #include <pichi/vo/rule.hpp>
9 
10 struct MMDB_s;
11 
12 namespace boost::asio::ip {
13 
14 class tcp;
15 template <typename Protocol> class basic_endpoint;
16 template <typename Protocol> class basic_resolver_results;
17 
18 }  // namespace boost::asio::ip
19 
20 namespace pichi {
21 
22 struct Endpoint;
23 
24 namespace api {
25 
26 extern bool matchPattern(std::string_view remote, std::string_view pattern);
27 extern bool matchDomain(std::string_view subdomain, std::string_view domain);
28 
29 class Geo {
30 public:
31   Geo(char const* fn);
32   ~Geo();
33 
34   Geo(Geo&&) noexcept = default;
35   Geo& operator=(Geo&&) noexcept = default;
36 
37   Geo(Geo const&) = delete;
38   Geo& operator=(Geo const&) = delete;
39 
40 public:
41   bool match(boost::asio::ip::basic_endpoint<boost::asio::ip::tcp> const&,
42              std::string_view country) const;
43 
44 private:
45   std::unique_ptr<MMDB_s> db_;
46 };
47 
48 class Router {
49 public:
50   using VO = vo::Rule;
51 
52 private:
53   using ResolvedResult = boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>;
54   using Matcher =
55       std::function<bool(Endpoint const&, ResolvedResult const&, std::string_view, AdapterType)>;
56   using Container = std::map<std::string, std::pair<VO, std::vector<Matcher>>, std::less<>>;
57   using DelegateIterator = typename Container::const_iterator;
58   using ValueType = std::pair<std::string_view, VO const&>;
59   using ConstIterator = vo::Iterator<DelegateIterator, ValueType>;
60 
61   static ValueType generatePair(DelegateIterator);
62 
63 public:
64   Router(char const* fn);
65 
66   std::string_view route(Endpoint const&, std::string_view ingress, AdapterType,
67                          ResolvedResult const&) const;
68 
69   void update(std::string const&, VO);
70   void erase(std::string_view);
71 
72   ConstIterator begin() const noexcept;
73   ConstIterator end() const noexcept;
74   bool isUsed(std::string_view) const;
75   bool needResloving() const;
76 
77   vo::Route getRoute() const;
78   void setRoute(vo::Route);
79 
80 private:
81   Geo geo_;
82   Container rules_ = {};
83   bool needResolving_ = false;
84   vo::Route route_ = {"direct"};
85 };
86 
87 }  // namespace api
88 }  // namespace pichi
89 
90 #endif  // PICHI_API_ROUTER_HPP
91