X-Git-Url: https://git.stg.codes/stg.git/blobdiff_plain/641204dfbdb9fc870cdd2e7f9e3169a44693e7bf..39c6313308afb248b140d98b8052f1b484549df2:/stglibs/pinger.lib/pinger.cpp diff --git a/stglibs/pinger.lib/pinger.cpp b/stglibs/pinger.lib/pinger.cpp index 9169b4e6..664367e8 100644 --- a/stglibs/pinger.lib/pinger.cpp +++ b/stglibs/pinger.lib/pinger.cpp @@ -1,22 +1,24 @@ -#include #include -#include #include #include #include #include #include #include -#include #include #include -#include -#include -#include -#include "pinger.h" -#include "common.h" -#include "stg_locker.h" +#include +#include +#include +#include +#include +#include + +#include "stg/common.h" +#include "stg/locker.h" + +#include "stg/pinger.h" #ifdef STG_TIME extern volatile time_t stgTime; @@ -24,365 +26,328 @@ extern volatile time_t stgTime; //----------------------------------------------------------------------------- STG_PINGER::STG_PINGER(time_t d) + : delay(d), + nonstop(false), + isRunningRecver(false), + isRunningSender(false), + sendSocket(-1), + recvSocket(-1), + sendThread(), + recvThread(), + pmSend(), + pid(0), + errorStr(), + pingIP(), + ipToAdd(), + ipToDel(), + mutex() { - delay = d; - pthread_mutex_init(&mutex, NULL); - pid = 0; +pthread_mutex_init(&mutex, NULL); +memset(&pmSend, 0, sizeof(pmSend)); } //----------------------------------------------------------------------------- STG_PINGER::~STG_PINGER() { - pthread_mutex_destroy(&mutex); +pthread_mutex_destroy(&mutex); } //----------------------------------------------------------------------------- int STG_PINGER::Start() { - struct protoent *proto = NULL; - proto = getprotobyname("ICMP"); - sendSocket = socket(PF_INET, SOCK_RAW, proto->p_proto); - recvSocket = socket(PF_INET, SOCK_RAW, proto->p_proto); - nonstop = true; - pid = (int) getpid() % 65535; - if (sendSocket < 0 || recvSocket < 0) - { - errorStr = "Cannot create socket."; - return -1; - } +struct protoent *proto = NULL; +proto = getprotobyname("ICMP"); +sendSocket = socket(PF_INET, SOCK_RAW, proto->p_proto); +recvSocket = socket(PF_INET, SOCK_RAW, proto->p_proto); +nonstop = true; +pid = (int) getpid() % 65535; +if (sendSocket < 0 || recvSocket < 0) + { + errorStr = "Cannot create socket."; + return -1; + } - if (pthread_create(&sendThread, NULL, RunSendPing, this)) - { - errorStr = "Cannot create send thread."; - return -1; - } +if (pthread_create(&sendThread, NULL, RunSendPing, this)) + { + errorStr = "Cannot create send thread."; + return -1; + } - if (pthread_create(&recvThread, NULL, RunRecvPing, this)) - { - errorStr = "Cannot create recv thread."; - return -1; - } +if (pthread_create(&recvThread, NULL, RunRecvPing, this)) + { + errorStr = "Cannot create recv thread."; + return -1; + } - return 0; +return 0; } //----------------------------------------------------------------------------- int STG_PINGER::Stop() { - close(recvSocket); - nonstop = false; - if (isRunningRecver) +close(recvSocket); +nonstop = false; +if (isRunningRecver) + { + //5 seconds to thread stops itself + for (size_t i = 0; i < 25; i++) { - //5 seconds to thread stops itself - int i; - for (i = 0; i < 25; i++) - { - if (i % 5 == 0) - SendPing(0x0100007f);//127.0.0.1 + if (i % 5 == 0) + SendPing(0x0100007f);//127.0.0.1 - if (!isRunningRecver) - break; + if (!isRunningRecver) + break; - usleep(200000); - } - - //after 5 seconds waiting thread still running. now killing it - if (isRunningRecver) - { - //if (pthread_kill(recvThread, SIGINT)) - // { - errorStr = "Cannot kill thread."; - return -1; - // } - //printf("recvThread killed\n"); - } + struct timespec ts = {0, 200000000}; + nanosleep(&ts, NULL); } + } - if (isRunningSender) +if (isRunningSender) + { + //5 seconds to thread stops itself + for (size_t i = 0; i < 25; i++) { - //5 seconds to thread stops itself - int i; - for (i = 0; i < 25; i++) - { - if (!isRunningSender) - break; - - usleep(200000); - } + if (!isRunningSender) + break; - //after 5 seconds waiting thread still running. now killing it - if (isRunningSender) - { - //if (pthread_kill(sendThread, SIGINT)) - // { - errorStr = "Cannot kill thread."; - return -1; - // } - //printf("sendThread killed\n"); - } + struct timespec ts = {0, 200000000}; + nanosleep(&ts, NULL); } + } - close(sendSocket); - return 0; +close(sendSocket); + +if (isRunningSender || isRunningRecver) + return -1; + +return 0; } //----------------------------------------------------------------------------- void STG_PINGER::AddIP(uint32_t ip) { - STG_LOCKER lock(&mutex, __FILE__, __LINE__); - //printf("AddIP\n"); - ipToAdd.push_back(ip); +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +ipToAdd.push_back(ip); } //----------------------------------------------------------------------------- void STG_PINGER::DelIP(uint32_t ip) { - STG_LOCKER lock(&mutex, __FILE__, __LINE__); - //printf("DelIP\n"); - ipToDel.push_back(ip); +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +ipToDel.push_back(ip); } //----------------------------------------------------------------------------- void STG_PINGER::RealAddIP() - { - STG_LOCKER lock(&mutex, __FILE__, __LINE__); +{ +STG_LOCKER lock(&mutex, __FILE__, __LINE__); - list::iterator iter; - iter = ipToAdd.begin(); - while (iter != ipToAdd.end()) - { - /*packets.insert(pair(rawPacket, ed));*/ - //pingIP[*iter] = 0; - pingIP.insert(pair(*iter, 0)); - iter++; - } - ipToAdd.erase(ipToAdd.begin(), ipToAdd.end()); +std::list::iterator iter; +iter = ipToAdd.begin(); +while (iter != ipToAdd.end()) + { + pingIP.insert(std::make_pair(*iter, 0)); + ++iter; } +ipToAdd.erase(ipToAdd.begin(), ipToAdd.end()); +} //----------------------------------------------------------------------------- void STG_PINGER::RealDelIP() { - STG_LOCKER lock(&mutex, __FILE__, __LINE__); +STG_LOCKER lock(&mutex, __FILE__, __LINE__); - list::iterator iter; - multimap::iterator treeIter; - iter = ipToDel.begin(); - while (iter != ipToDel.end()) - { - treeIter = pingIP.find(*iter); - //printf("Found %X\n", *iter); - if (treeIter != pingIP.end()) - pingIP.erase(treeIter); +std::list::iterator iter; +std::multimap::iterator treeIter; +iter = ipToDel.begin(); +while (iter != ipToDel.end()) + { + treeIter = pingIP.find(*iter); + if (treeIter != pingIP.end()) + pingIP.erase(treeIter); - iter++; - } - ipToDel.erase(ipToDel.begin(), ipToDel.end()); -} -//----------------------------------------------------------------------------- -int STG_PINGER::GetPingIPNum() -{ - return pingIP.size(); + ++iter; + } +ipToDel.erase(ipToDel.begin(), ipToDel.end()); } //----------------------------------------------------------------------------- -void STG_PINGER::GetAllIP(vector *) +int STG_PINGER::GetPingIPNum() const { - //STG_LOCKER lock(&mutex, __FILE__, __LINE__); +return pingIP.size(); } //----------------------------------------------------------------------------- void STG_PINGER::PrintAllIP() { - STG_LOCKER lock(&mutex, __FILE__, __LINE__); - multimap::iterator iter; - iter = pingIP.begin(); - while (iter != pingIP.end()) - { - uint32_t ip = iter->first; - time_t t = iter->second; - string s; - x2str(t, s); - printf("ip = %s, time = %9s\n", inet_ntostring(ip).c_str(), s.c_str()); - iter++; - } +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +std::multimap::iterator iter; +iter = pingIP.begin(); +while (iter != pingIP.end()) + { + uint32_t ip = iter->first; + time_t t = iter->second; + std::string s; + x2str(t, s); + printf("ip = %s, time = %9s\n", inet_ntostring(ip).c_str(), s.c_str()); + ++iter; + } } //----------------------------------------------------------------------------- -int STG_PINGER::GetIPTime(uint32_t ip, time_t * t) +int STG_PINGER::GetIPTime(uint32_t ip, time_t * t) const { - STG_LOCKER lock(&mutex, __FILE__, __LINE__); - multimap::iterator treeIter; +STG_LOCKER lock(&mutex, __FILE__, __LINE__); +std::multimap::const_iterator treeIter; - treeIter = pingIP.find(ip); - if (treeIter == pingIP.end()) - return -1; +treeIter = pingIP.find(ip); +if (treeIter == pingIP.end()) + return -1; - *t = treeIter->second; - return 0; -} -//----------------------------------------------------------------------------- -void STG_PINGER::SetDelayTime(time_t d) -{ - delay = d; -} -//----------------------------------------------------------------------------- -time_t STG_PINGER::GetDelayTime() -{ - return delay; -} -//----------------------------------------------------------------------------- -string STG_PINGER::GetStrError() -{ - return errorStr; +*t = treeIter->second; +return 0; } //----------------------------------------------------------------------------- uint16_t STG_PINGER::PingCheckSum(void * data, int len) { - unsigned short * buf = (unsigned short *)data; - unsigned int sum = 0; - unsigned short result; +unsigned short * buf = (unsigned short *)data; +unsigned int sum = 0; +unsigned short result; - for ( sum = 0; len > 1; len -= 2 ) - sum += *buf++; +for ( sum = 0; len > 1; len -= 2 ) + sum += *buf++; - if ( len == 1 ) - sum += *(unsigned char*)buf; +if ( len == 1 ) + sum += *(unsigned char*)buf; - sum = (sum >> 16) + (sum & 0xFFFF); - sum += (sum >> 16); - result = ~sum; - return result; +sum = (sum >> 16) + (sum & 0xFFFF); +sum += (sum >> 16); +result = ~sum; +return result; } //----------------------------------------------------------------------------- int STG_PINGER::SendPing(uint32_t ip) { - struct sockaddr_in addr; - //printf("SendPing %X \n", ip); - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = 0; - addr.sin_addr.s_addr = ip; +struct sockaddr_in addr; +memset(&addr, 0, sizeof(addr)); +addr.sin_family = AF_INET; +addr.sin_port = 0; +addr.sin_addr.s_addr = ip; - memset(&pmSend, 0, sizeof(pmSend)); - pmSend.hdr.type = ICMP_ECHO; - pmSend.hdr.un.echo.id = pid; - memcpy(pmSend.msg, &ip, sizeof(ip)); +memset(&pmSend, 0, sizeof(pmSend)); +pmSend.hdr.type = ICMP_ECHO; +pmSend.hdr.un.echo.id = pid; +memcpy(pmSend.msg, &ip, sizeof(ip)); - pmSend.hdr.checksum = PingCheckSum(&pmSend, sizeof(pmSend)); +pmSend.hdr.checksum = PingCheckSum(&pmSend, sizeof(pmSend)); - if (sendto(sendSocket, &pmSend, sizeof(pmSend), 0, (sockaddr *)&addr, sizeof(addr)) <= 0 ) - { - errorStr = "Send ping error: " + string(strerror(errno)); - return -1; - } +if (sendto(sendSocket, &pmSend, sizeof(pmSend), 0, (sockaddr *)&addr, sizeof(addr)) <= 0 ) + { + errorStr = "Send ping error: " + std::string(strerror(errno)); + return -1; + } - return 0; +return 0; } //----------------------------------------------------------------------------- uint32_t STG_PINGER::RecvPing() { - struct sockaddr_in addr; - uint32_t ipAddr = 0; +struct sockaddr_in addr; +uint32_t ipAddr = 0; - char buf[128]; - memset(buf, 0, sizeof(buf)); - int bytes; - socklen_t len = sizeof(addr); +char buf[128]; +memset(buf, 0, sizeof(buf)); +int bytes; +socklen_t len = sizeof(addr); - bytes = recvfrom(recvSocket, &buf, sizeof(buf), 0, (struct sockaddr*)&addr, &len); - //printf("recvfrom\n"); - if (bytes > 0) - { - struct IP_HDR * ip = (struct IP_HDR *)buf; - struct ICMP_HDR *icmp = (struct ICMP_HDR *)(buf + ip->ihl * 4); +bytes = recvfrom(recvSocket, &buf, sizeof(buf), 0, (struct sockaddr*)&addr, &len); +if (bytes > 0) + { + struct IP_HDR * ip = (struct IP_HDR *)buf; + struct ICMP_HDR *icmp = (struct ICMP_HDR *)(buf + ip->ihl * 4); - //printf("icmp->un.echo.id=%d, pid=%d, tid: %d\n", icmp->un.echo.id, pid); - if (icmp->un.echo.id != pid) - return 0; + if (icmp->un.echo.id != pid) + return 0; - ipAddr = *(uint32_t*)(buf + sizeof(ICMP_HDR) + ip->ihl * 4); - } + ipAddr = *(uint32_t*)(buf + sizeof(ICMP_HDR) + ip->ihl * 4); + } - return ipAddr; +return ipAddr; } //----------------------------------------------------------------------------- void * STG_PINGER::RunSendPing(void * d) { - STG_PINGER * pinger = (STG_PINGER*)d; +sigset_t signalSet; +sigfillset(&signalSet); +pthread_sigmask(SIG_BLOCK, &signalSet, NULL); + +STG_PINGER * pinger = static_cast(d); + +pinger->isRunningSender = true; +time_t lastPing = 0; +while (pinger->nonstop) + { + pinger->RealAddIP(); + pinger->RealDelIP(); - pinger->isRunningSender = true; - time_t lastPing = 0; - while (pinger->nonstop) + std::multimap::iterator iter; + iter = pinger->pingIP.begin(); + while (iter != pinger->pingIP.end()) { - pinger->RealAddIP(); - pinger->RealDelIP(); + pinger->SendPing(iter->first); + ++iter; + } - multimap::iterator iter; - iter = pinger->pingIP.begin(); - while (iter != pinger->pingIP.end()) - { - uint32_t ip = iter->first; - pinger->SendPing(ip); - iter++; - } + time_t currTime; - time_t currTime; + #ifdef STG_TIME + lastPing = stgTime; + currTime = stgTime; + #else + currTime = lastPing = time(NULL); + #endif + while (currTime - lastPing < pinger->delay && pinger->nonstop) + { #ifdef STG_TIME - lastPing = stgTime; currTime = stgTime; #else - currTime = lastPing = time(NULL); + currTime = time(NULL); #endif - - while (currTime - lastPing < pinger->delay && pinger->nonstop) - { - #ifdef STG_TIME - currTime = stgTime; - #else - currTime = time(NULL); - #endif - usleep(20000); - } - //printf("new ping cycle\n"); + struct timespec ts = {0, 20000000}; + nanosleep(&ts, NULL); } + } - pinger->isRunningSender = false; +pinger->isRunningSender = false; - return NULL; +return NULL; } //----------------------------------------------------------------------------- void * STG_PINGER::RunRecvPing(void * d) { - STG_PINGER * pinger = (STG_PINGER*)d; +sigset_t signalSet; +sigfillset(&signalSet); +pthread_sigmask(SIG_BLOCK, &signalSet, NULL); - pinger->isRunningRecver = true; +STG_PINGER * pinger = static_cast(d); - uint32_t ip; - multimap::iterator treeIterLower; - multimap::iterator treeIterUpper; +pinger->isRunningRecver = true; - while (pinger->nonstop) - { - ip = pinger->RecvPing(); +while (pinger->nonstop) + { + uint32_t ip = pinger->RecvPing(); - if (ip) + if (ip) + { + std::multimap::iterator treeIterUpper = pinger->pingIP.upper_bound(ip); + std::multimap::iterator treeIterLower = pinger->pingIP.lower_bound(ip); + while (treeIterUpper != treeIterLower) { - //printf("RecvPing %X\n", ip); - treeIterUpper = pinger->pingIP.upper_bound(ip); - treeIterLower = pinger->pingIP.lower_bound(ip); - int i = 0; - while (treeIterUpper != treeIterLower) - //treeIterUpper = pinger->pingIP.find(ip); - //if (treeIterUpper != pinger->pingIP.end()) - { - //printf("+++! time=%d %X i=%d !+++\n", time(NULL), ip, i); - //printf("--- time=%d ---\n", time(NULL)); - #ifdef STG_TIME - treeIterLower->second = stgTime; - #else - treeIterLower->second = time(NULL); - #endif - ++treeIterLower; - i++; - } + #ifdef STG_TIME + treeIterLower->second = stgTime; + #else + treeIterLower->second = time(NULL); + #endif + ++treeIterLower; } - } - pinger->isRunningRecver = false; - return NULL; + + } +pinger->isRunningRecver = false; +return NULL; } //----------------------------------------------------------------------------- -