X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/703ad5b9a14dc2a42849669d3618a8ba1136bb92..719325d30f713accc04c83c6951ff2a6bfcf33e0:/include/stg/user_ips.h?ds=sidebyside diff --git a/include/stg/user_ips.h b/include/stg/user_ips.h index 17bb59be..35c20925 100644 --- a/include/stg/user_ips.h +++ b/include/stg/user_ips.h @@ -18,14 +18,15 @@ * Author : Boris Mikhailenko */ - /* - $Revision: 1.22 $ - $Date: 2010/03/04 11:49:53 $ - $Author: faust $ - */ +#pragma once + +#include "stg/common.h" -#ifndef USER_IPS_H -#define USER_IPS_H +#include +#include +#include +#include +#include #ifdef FREE_BSD #include @@ -35,246 +36,180 @@ #include #include -#include -#include -#include -#include -#include - -#include "stg/common.h" -#include "os_int.h" - -using namespace std; +namespace STG +{ //------------------------------------------------------------------------- -struct IP_MASK +struct IPMask { -IP_MASK() : ip(0), mask(0) {} -IP_MASK(const IP_MASK & ipm) : ip(ipm.ip), mask(ipm.mask) {} -uint32_t ip; -uint32_t mask; + IPMask() noexcept : ip(0), mask(0) {} + IPMask(uint32_t i, uint32_t m) noexcept : ip(i), mask(m) {} + + IPMask(const IPMask&) = default; + IPMask& operator=(const IPMask&) = default; + IPMask(IPMask&&) = default; + IPMask& operator=(IPMask&&) = default; + + uint32_t ip; + uint32_t mask; }; //------------------------------------------------------------------------- -class USER_IPS +class UserIPs { - friend std::ostream & operator<< (ostream & o, const USER_IPS & i); - //friend stringstream & operator<< (stringstream & s, const USER_IPS & i); - friend const USER_IPS StrToIPS(const string & ipsStr) throw(string); - -public: - USER_IPS(); - USER_IPS(const USER_IPS &); - USER_IPS & operator=(const USER_IPS &); - const IP_MASK & operator[](int idx) const; - std::string GetIpStr() const; - bool IsIPInIPS(uint32_t ip) const; - bool OnlyOneIP() const; - int Count() const; - void Add(const IP_MASK &im); - void Erase(); - -private: - uint32_t CalcMask(unsigned int msk) const; - std::vector ips; + friend std::ostream & operator<< (std::ostream & o, const UserIPs & i); + + public: + using ContainerType = std::vector; + using IndexType = ContainerType::size_type; + + UserIPs() = default; + + UserIPs(const UserIPs&) = default; + UserIPs& operator=(const UserIPs&) = default; + UserIPs(UserIPs&&) = default; + UserIPs& operator=(UserIPs&&) = default; + + static UserIPs parse(const std::string& source); + + const IPMask& operator[](IndexType idx) const noexcept { return ips[idx]; } + std::string toString() const noexcept; + bool find(uint32_t ip) const noexcept; + bool onlyOneIP() const noexcept; + bool isAnyIP() const noexcept; + size_t count() const noexcept { return ips.size(); } + void add(const IPMask& im) noexcept{ ips.push_back(im); } + + private: + uint32_t calcMask(unsigned int msk) const noexcept; + ContainerType ips; }; //------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -inline -USER_IPS::USER_IPS() - : ips() -{} -//----------------------------------------------------------------------------- -inline -USER_IPS::USER_IPS(const USER_IPS & i) - : ips(i.ips) -{} -//----------------------------------------------------------------------------- inline -USER_IPS & USER_IPS::operator=(const USER_IPS & i) +std::string UserIPs::toString() const noexcept { -ips = i.ips; -return *this; + if (ips.empty()) + return ""; + + if (ips[0].ip == 0) + return "*"; + + auto it = ips.begin(); + std::string res = inet_ntostring(it->ip); + ++it; + for (; it != ips.end(); ++it) + res += "," + inet_ntostring(it->ip); + return res; } //----------------------------------------------------------------------------- inline -const IP_MASK & USER_IPS::operator[](int idx) const +uint32_t UserIPs::calcMask(unsigned int msk) const noexcept { -return ips[idx]; + if (msk > 32) + return 0; + return htonl(0xFFffFFff << (32 - msk)); } //----------------------------------------------------------------------------- inline -std::string USER_IPS::GetIpStr() const +bool UserIPs::find(uint32_t ip) const noexcept { -if (ips.empty()) - { - return ""; - } + if (ips.empty()) + return false; -if (ips[0].ip == 0) - { - return "*"; - } + if (ips.front().ip == 0) + return true; -std::vector::const_iterator it(ips.begin()); -std::stringstream s; -s << inet_ntostring(it->ip); -++it; -for (; it != ips.end(); ++it) + for (auto it = ips.begin(); it != ips.end(); ++it) { - s << "," << inet_ntostring(it->ip); + const auto mask = calcMask(it->mask); + if ((ip & mask) == (it->ip & mask)) + return true; } -return s.str(); -} -//----------------------------------------------------------------------------- -inline -int USER_IPS::Count() const -{ -return ips.size(); -} -//----------------------------------------------------------------------------- -inline -bool USER_IPS::IsIPInIPS(uint32_t ip) const -{ -if (ips.empty()) - { return false; - } - -if (ips.front().ip == 0) - return true; - -for (std::vector::const_iterator it(ips.begin()); it != ips.end(); ++it) - { - uint32_t mask(CalcMask(it->mask)); - if ((ip & mask) == (it->ip & mask)) - return true; - } -return false; } //----------------------------------------------------------------------------- inline -bool USER_IPS::OnlyOneIP() const +bool UserIPs::onlyOneIP() const noexcept { -if (ips.size() == 1 && ips.front().mask == 32) - return true; + if (ips.size() == 1 && ips.front().mask == 32 && ips.front().ip != 0) + return true; -return false; -} -//----------------------------------------------------------------------------- -inline -uint32_t USER_IPS::CalcMask(unsigned int msk) const -{ -if (msk > 32) - return 0; -return htonl(0xFFffFFff << (32 - msk)); -} -//----------------------------------------------------------------------------- -inline -void USER_IPS::Add(const IP_MASK &im) -{ -ips.push_back(im); + return false; } //----------------------------------------------------------------------------- inline -void USER_IPS::Erase() +bool UserIPs::isAnyIP() const noexcept { -ips.erase(ips.begin(), ips.end()); + return !ips.empty() && ips.front().ip == 0; } //----------------------------------------------------------------------------- inline -std::ostream & operator<<(std::ostream & o, const USER_IPS & i) +std::ostream & operator<<(std::ostream& o, const UserIPs& i) { -return o << i.GetIpStr(); + return o << i.toString(); } //----------------------------------------------------------------------------- -/*inline -stringstream & operator<<(std::stringstream & s, const USER_IPS & i) -{ -s << i.GetIpStr(); -return s; -}*/ -//----------------------------------------------------------------------------- inline -const USER_IPS StrToIPS(const std::string & ipsStr) throw(std::string) +UserIPs UserIPs::parse(const std::string& source) { -USER_IPS ips; -char * paddr; -IP_MASK im; -std::vector ipMask; -std::string err; -if (ipsStr.empty()) - { - return ips; - } + if (source.empty()) + return {}; -if (ipsStr[0] == '*' && ipsStr.size() == 1) + UserIPs ips; + if (source[0] == '*' && source.size() == 1) { - im.ip = 0; - im.mask = 0; - ips.ips.push_back(im); - return ips; + ips.ips.push_back(IPMask()); + return ips; } -char * str = new char[ipsStr.size() + 1]; -strcpy(str, ipsStr.c_str()); -char * pstr = str; -while ((paddr = strtok(pstr, ","))) + std::vector ipMask; + char * tmp = new char[source.size() + 1]; + strcpy(tmp, source.c_str()); + char * pstr = tmp; + char * paddr = NULL; + while ((paddr = strtok(pstr, ","))) { - pstr = NULL; - ipMask.push_back(paddr); + pstr = NULL; + ipMask.push_back(paddr); } -delete[] str; + delete[] tmp; -for (unsigned int i = 0; i < ipMask.size(); i++) + for (UserIPs::IndexType i = 0; i < ipMask.size(); i++) { - char str[128]; - char * strIp; - char * strMask; - strcpy(str, ipMask[i].c_str()); - strIp = strtok(str, "/"); - if (strIp == NULL) - { - err = "Incorrect IP address " + ipsStr; - return ips; - } - strMask = strtok(NULL, "/"); + char str[128]; + char * strIp; + char * strMask; + strcpy(str, ipMask[i].c_str()); + strIp = strtok(str, "/"); + if (strIp == NULL) + return ips; + strMask = strtok(NULL, "/"); - im.ip = inet_addr(strIp); - if (im.ip == INADDR_NONE) - { - err = "Incorrect IP address: " + std::string(strIp); - return ips; - } + IPMask im; - im.mask = 32; - if (strMask != NULL) - { - int m = 0; - if (str2x(strMask, m) != 0) - { - err = "Incorrect mask: " + std::string(strMask); + im.ip = inet_addr(strIp); + if (im.ip == INADDR_NONE) return ips; - } - im.mask = m; - if (im.mask > 32) - { - err = "Incorrect mask: " + std::string(strMask); - return ips; - } + im.mask = 32; + if (strMask != NULL) + { + int m = 0; + if (str2x(strMask, m) != 0) + return ips; + im.mask = m; - if ((im.ip & ips.CalcMask(im.mask)) != im.ip) - { - err = "Address does'n match mask: " + std::string(strIp) + "/" + std::string(strMask); - return ips; - } + if (im.mask > 32) + return ips; + + if ((im.ip & ips.calcMask(im.mask)) != im.ip) + return ips; } - ips.ips.push_back(im); + ips.ips.push_back(im); } -return ips; + return ips; } //------------------------------------------------------------------------- -#endif //USER_IPS_H +}