ferencd@0: #ifndef FLOOD_CHECK ferencd@0: #define FLOOD_CHECK ferencd@0: ferencd@0: #include ferencd@0: #include ferencd@0: #include ferencd@0: #include ferencd@0: ferencd@0: /** ferencd@0: * @brief The flood_check class will check if there is a flood attempt from some specific ferencd@0: * IP. The following is the method: If it can identify that in a given second a given IP ferencd@0: * has tried more than 100 (configurable) requests it will reject the requests without ferencd@0: * going further. ferencd@0: */ ferencd@0: class flood_check ferencd@0: { ferencd@0: public: ferencd@0: ferencd@0: static void attempt(std::string ip); ferencd@0: ferencd@0: private: ferencd@0: ferencd@0: static std::mutex locker; ferencd@0: ferencd@0: // holds the flood attempts and when they have first occured ferencd@0: struct count_started ferencd@0: { ferencd@0: int count = 0; ferencd@0: std::time_t first_time = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); ferencd@0: }; ferencd@0: ferencd@0: // structures used to determine the flood rate / second ferencd@0: using flood_map = std::map; ferencd@0: static std::map floods; ferencd@0: ferencd@0: // holds the flood attempts of a host. For each IP we have an attempt counter ferencd@0: // how many times it tried to flood us and when the last attempt happened ferencd@0: static std::map hostd_flood; ferencd@0: ferencd@0: // holds the evil hosts that are flooding the system and how long they are locked out ferencd@0: // the content of this map is determined based on the content of the hostd_flood ferencd@0: // map. If a count from there reaches over 10 and the first_time of the ferencd@0: // entry is < 1 minute then we consider the host flooding us. ferencd@0: static std::map rejected_hosts; ferencd@0: ferencd@0: // holds how many times the given host was suspended. Each suspension will give another minute to the host ferencd@0: static std::map suspension_times; ferencd@0: }; ferencd@0: ferencd@0: #endif // FLOOD_CHECK ferencd@0: