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