#include "IPLimit.h" #include #include #include #include #include #include #include #include "myLog.h" using namespace IPRateLimit; using boost::multi_index_container; using namespace boost::multi_index; using namespace boost::interprocess; //iprate_con* CIPLimit::con = NULL; //pthread_mutex_t* CIPLimit::mutex = NULL; //bip::managed_mapped_file* CIPLimit::seg = NULL; //int CIPLimit::maxCount = 0; uint32_t CIPLimit::IPStr2Int(const char* pStr) { return ntohl(inet_addr(pStr)); } void CIPLimit::IPInt2Str(uint32_t ip,char *pIP) { uint32_t nip = htonl(ip); struct in_addr addr; addr.s_addr = nip; strcpy(pIP,inet_ntoa(addr)); } void CIPLimit::time2str(time_t t,std::string &str) { struct tm t1; localtime_r(&t,&t1); char buf[64] = {0}; strftime(buf,sizeof(buf),"%Y-%m-%d %H:%M:%S",&t1); str = buf; } int CIPLimit::init() { //maxCount = count; try { //m_seg = bip::managed_mapped_file(bip::open_or_create, shm_name, count*sizeof(iprate)*8); //m_mutex = bip::named_mutex(bip::open_or_create,shm_name); con = m_seg.find_or_construct("iplimitcontainer")( iprate_con::ctor_args_list(), iprate_con::allocator_type(m_seg.get_segment_manager())); if(!con) return -3; //return MyProMutex::init(mutex_ipc_key,&mutex,bInitMutex); } catch(boost::interprocess::interprocess_exception& e) { MYLOG_ERROR(logger,"exception %s",e.what()); return -4; } return 0; } /*bool CIPLimit::lock() { return MyProMutex::lock(mutex); } void CIPLimit::unlock() { MyProMutex::unlock(mutex); } int CIPLimit::destroyMutex() { return pthread_mutex_destroy(mutex); }*/ CIPLimit::CIPLimit(const char *shm_name, const long count):con(NULL),m_mutex(bip::open_or_create,shm_name),m_seg(bip::open_or_create, shm_name, count*sizeof(iprate)*8),maxCount(count) { //ctor } CIPLimit::~CIPLimit() { //dtor } struct modify_data { modify_data(const iprate &data):v(data) {} void operator()(iprate& data) { data = v; } private: iprate v; }; int CIPLimit::getSecCountGreaterThan(int minNum,std::vector &data) { try { scoped_lock lock(m_mutex); /*MyProMutex::CAutoRelease mtx(mutex); if(mtx.bret == false) return -1;*/ secCountIdx &idx = get(*con); secCountIdx::const_iterator iter = idx.lower_bound(minNum); for(;iter != idx.end();iter++) { data.push_back(*iter); } } catch(boost::interprocess::interprocess_exception& e) { MYLOG_ERROR(logger,"free mem %d,con.size %d,exception %s",m_seg.get_free_memory(),con->size(),e.what()); return -2; } return 0; } int CIPLimit::getMinCountGreaterThan(int minNum,std::vector &data) { try { scoped_lock lock(m_mutex); /*MyProMutex::CAutoRelease mtx(mutex); if(mtx.bret == false) return -1;*/ minCountIdx &idx = get(*con); minCountIdx::const_iterator iter = idx.lower_bound(minNum); for(;iter != idx.end();iter++) { data.push_back(*iter); } } catch(boost::interprocess::interprocess_exception& e) { MYLOG_ERROR(logger,"free mem %d,con.size %d,exception %s",m_seg.get_free_memory(),con->size(),e.what()); return -1; } return 0; } int CIPLimit::getHourCountGreaterThan(int minNum,std::vector &data) { try { scoped_lock lock(m_mutex); /*MyProMutex::CAutoRelease mtx(mutex); if(mtx.bret == false) return -1;*/ hourCountIdx &idx = get(*con); hourCountIdx::const_iterator iter = idx.lower_bound(minNum); for(;iter != idx.end();iter++) { data.push_back(*iter); } } catch(boost::interprocess::interprocess_exception& e) { MYLOG_ERROR(logger,"free mem %d,con.size %d,exception %s",m_seg.get_free_memory(),con->size(),e.what()); return -1; } return 0; } int CIPLimit::getDayCountGreaterThan(int minNum,std::vector &data) { try { scoped_lock lock(m_mutex); /*MyProMutex::CAutoRelease mtx(mutex); if(mtx.bret == false) return -1;*/ dayCountIdx &idx = get(*con); dayCountIdx::const_iterator iter = idx.lower_bound(minNum); for(;iter != idx.end();iter++) { data.push_back(*iter); } } catch(boost::interprocess::interprocess_exception& e) { MYLOG_ERROR(logger,"free mem %d,con.size %d,exception %s",m_seg.get_free_memory(),con->size(),e.what()); return -1; } return 0; } int CIPLimit::getDataGreaterThan(int minNum,const ENUM_TYPE etype,std::vector &data) { if(etype == ESEC_COUNT) { return getSecCountGreaterThan(minNum,data); } else if(etype == EMIN_COUNT) { return getMinCountGreaterThan(minNum,data); } else if(etype == EHOUR_COUNT) { return getHourCountGreaterThan(minNum,data); } else if(etype == EDAY_COUNT) { return getDayCountGreaterThan(minNum,data); } else { return -1; } } int CIPLimit::incCount(uint32_t ip,iprate &data) { try { scoped_lock lock(m_mutex); /* MyProMutex::CAutoRelease mtx(mutex); if(mtx.bret == false) { printf("lock ret false\n"); return -1; }*/ ipIdx &idx = get(*con); ipIdx::const_iterator iter = idx.find(ip); //ipIdx::const_iterator iter = get(*con).find(ip); time_t t = time(NULL); if(iter != idx.end()) { data = (*iter); //printf("---- %d,%d,%d,%d\n",data.countSec,data.countMin,data.countHour,data.countDay); int diffSec = t - data.tmSec; int diffMin = t - data.tmMin; int diffHour = t - data.tmHour; int diffDay = t - data.tmDay; //printf("diff %d,%d,%d,%d\n",diffSec,diffMin,diffHour,diffDay); if(diffSec <= 1) { ++data.countSec; } else { data.countSec = 1; data.tmSec = t; } if(diffMin <= 60) { ++data.countMin; } else { data.countMin = 1; data.tmMin = t; } if(diffHour <= 60*60) { ++data.countHour; } else { data.countHour = 1; data.tmHour = t; } if(diffDay <= 60*60*24) { ++data.countDay; } else { data.countDay = 1; data.tmDay = t; } //printf(">>%d,%d,%d,%d\n",data.countSec,data.countMin,data.countHour,data.countDay); idx.modify(iter,modify_data(data)); } else { iprate d; d.ip = ip; d.tmSec = t; d.tmMin = t; d.tmHour = t; d.tmDay = t; d.countSec = 1; d.countMin = 1; d.countHour = 1; d.countDay = 1; if((int)con->size() >= maxCount ) { dayCountIdx &dayIdx = get(*con); dayCountIdx::const_iterator it = dayIdx.begin(); //printf("min %d,%d,%d,%d\n",it->countSec,it->countMin,it->countHour,it->countDay); dayIdx.modify(it,modify_data(d)); } else { con->insert(d); } data = d; } } catch(boost::interprocess::interprocess_exception& e) { MYLOG_ERROR(logger,"free mem %d,con.size %d,exception %s",m_seg.get_free_memory(),con->size(),e.what()); return -4; } return 0; }