double diffTime(TimeStamp &previousTime, TimeStamp ¤tTime) { double diffSeconds = currentTime.seconds() - previousTime.seconds(); int32_t diffMicroseconds = currentTime.microseconds() - previousTime.microseconds(); if (diffMicroseconds < 0) { --diffSeconds; diffMicroseconds += 1000000; } return (diffSeconds + (static_cast<double>(diffMicroseconds)/1000000)); }
std::string getDisplayTime(const TimeStamp timeStamp) { std::ostringstream timeString; if (timeStamp.seconds()) { timeString << getSQLTime(timeStamp.seconds()).getDateTime() << '.' << std::setw(6) << std::setfill('0') << timeStamp.microseconds(); return timeString.str(); } return "Not seen"; }
bool NameResolution::getLastResolutionTime(TimeStamp &ret, const uint32_t &host, const uint32_t &resolvedIP, const TimeStamp &t, ims::name::NameResolutionSourceType sourceType) { // prepare the command cmdLen = 19; // uint16_t tmpCmdLen = htons(cmdLen); memcpy(buf, &tmpCmdLen, sizeof(uint16_t)); buf[2] = 0; // type, NameResolution buf[3] = 7; // function, getLastResolutionTime if (sourceType == ims::name::NameResolutionSourceType::ANY) { buf[4] = 0; } else if (sourceType == ims::name::NameResolutionSourceType::DNS) { buf[4] = 1; } this -> ip = htonl(host); memcpy(buf + 5, &(this -> ip), sizeof(uint32_t)); // arg (host) this -> ip = htonl(resolvedIP); memcpy(buf + 9, &(this -> ip), sizeof(uint32_t)); // arg (resolvedIP) this -> ip = htonl(t.seconds()); memcpy(buf + 13, &(this -> ip), sizeof(uint32_t)); // arg (seconds) this -> ip = htonl(t.microseconds()); memcpy(buf + 17, &(this -> ip), sizeof(uint32_t)); // arg (microseconds) // issue the command if (socket_write(conn_fd, buf, cmdLen + 2, sockTimeout) != cmdLen + 2) { // something went wrong...reconnect, try one more time, then fail close(conn_fd); if (!establishConnection()) { return false; } if (socket_write(conn_fd, buf, cmdLen + 2, sockTimeout) != cmdLen + 2) { return false; } } // at this point, all is well, and command has been issued // read back the answer if (socket_read(conn_fd, (char *) &ret, sizeof(ret), sockTimeout) != sizeof(ret)) { // error return false; } ret.set(ntohl(ret.seconds()), ntohl(ret.microseconds())); return true; }
bool NameResolution::load(const TimeStamp &begin, const TimeStamp &end, ims::name::NameResolutionSourceType sourceType) { // prepare the command cmdLen = 19; // uint16_t tmpCmdLen = htons(cmdLen); memcpy(buf, &tmpCmdLen, sizeof(uint16_t)); buf[2] = 0; // type, NameResolution buf[3] = -2; // function, load if (sourceType == ims::name::NameResolutionSourceType::ANY) { buf[4] = 0; } else if (sourceType == ims::name::NameResolutionSourceType::DNS) { buf[4] = 1; } this -> ip = htonl(begin.seconds()); memcpy(buf + 5, &(this -> ip), sizeof(uint32_t)); // arg (t) this -> ip = htonl(begin.microseconds()); memcpy(buf + 9, &(this -> ip), sizeof(uint32_t)); // arg (t) this -> ip = htonl(end.seconds()); memcpy(buf + 13, &(this -> ip), sizeof(uint32_t)); // arg (t) this -> ip = htonl(end.microseconds()); memcpy(buf + 17, &(this -> ip), sizeof(uint32_t)); // arg (t) // issue the command if (socket_write(conn_fd, buf, cmdLen + 2, sockTimeout) != cmdLen + 2) { // something went wrong...reconnect, try one more time, then fail close(conn_fd); if (!establishConnection()) { return false; } if (socket_write(conn_fd, buf, cmdLen + 2, sockTimeout) != cmdLen + 2) { return false; } } if (socket_read(conn_fd, buf, 1, sockTimeout) != 1) { // error return false; } return true; }
bool TimeStamp::operator>(const TimeStamp &right) const { if (_seconds != right.seconds()) { return (_seconds > right.seconds()); } return (_microseconds > right.microseconds()); }
bool TimeStamp::operator==(const TimeStamp &right) const { return (_seconds == right.seconds() && _microseconds == right.microseconds()); }
int processNameResCmd(int fd, char *buf, size_t len, NameResolutionResponseBuffs &nameResBuffs) { NameResolutionSourceType stype; unsigned char ch; uint16_t count; uint32_t count32; ssize_t ret; uint32_t tmpIP; TimeStamp t; if (len < 2) { //wtF? cerr << "len error" << endl; return -1; } switch (buf[1]) { case 0: // ANY stype = NameResolutionSourceType::ANY; break; case 1: // DNS stype = NameResolutionSourceType::DNS; break; default: // return error cerr << "type error" << endl; return -1; }; TimeStamp begin, end; switch (buf[0]) { case 0: //getIPsFromName //cerr << "Case 0" << endl; if (len != (3 + (unsigned char) buf[2])) { // return error return -1; } nameResBuffs.ips.clear(); nameResMan.getIPsFromName(nameResBuffs.ips, string(buf + 3, (size_t) (unsigned char) buf[2]), stype); // write the number of ips... count = nameResBuffs.ips.size(); count = htons(count); if ((ret = socket_write(fd, (char *) &count, 2, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 2) { cerr << "socket_write() timeout." << endl; return -1; } // write the ips for (IPSet::iterator it = nameResBuffs.ips.begin(); it != nameResBuffs.ips.end(); ++it) { tmpIP = htonl(*it); if ((ret = socket_write(fd, (char *) &tmpIP, 4, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 4) { cerr << "socket_write() timeout." << endl; return -1; } } break; case 1: //getNamesFromIP //cerr << "Case 1" << endl; if (len != 6) { // return error cerr << "len: " << len << endl; return -1; } nameResBuffs.names.clear(); nameResMan.getNamesFromIP(nameResBuffs.names, ntohl(*(uint32_t *) (buf + 2)), stype); // write the number of names count = nameResBuffs.names.size(); count = htons(count); // write the number of names if ((ret = socket_write(fd, (char *) &count, 2, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 2) { cerr << "socket_write() timeout." << endl; return -1; } // write the names for (NameSet::iterator it = nameResBuffs.names.begin(); it != nameResBuffs.names.end(); ++it) { // write the name length ch = it -> length(); if ((ret = socket_write(fd, (char *) &ch, 1, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 1) { cerr << "socket_write() timeout." << endl; return -1; } // write the name if ((ret = socket_write(fd, it -> c_str(), it -> length(), queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != it -> length()) { cerr << "socket_write() timeout." << endl; return -1; } } //socket_write(fd, "Hello", 5, queryManConfig.sockTimeout); break; case 2: //hasMappingName //cerr << "Case 2" << endl; if (len != (3 + (unsigned char) buf[2])) { // return error return -1; } ch = (nameResMan.hasMapping(string(buf + 3, (size_t) (unsigned char) buf[2]), stype))?1:0; if ((ret = socket_write(fd, (char *) &ch, 1, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 1) { cerr << "socket_write() timeout." << endl; return -1; } break; case 3: //hasMappingIP //cerr << "Case 3" << endl; if (len != 6) { // return error return -1; } ch = (nameResMan.hasMapping(ntohl(*(uint32_t *) (buf + 2)), stype))?1:0; if ((ret = socket_write(fd, (char *) &ch, 1, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 1) { cerr << "socket_write() timeout." << endl; return -1; } break; case 4: //getMappings //cerr << "Case 4" << endl; if (len != 2) { // return error return -1; } nameResMan.getMappings(nameResBuffs.mappings, stype); // write the number of names assert(nameResBuffs.mappings.size() <= 0xffffffff); count32 = nameResBuffs.mappings.size(); count32 = htonl(count32); if ((ret = socket_write(fd, (char *) &count32, 4, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 4) { cerr << "socket_write() timeout." << endl; return -1; } // write the mappings for (NameIPMap::iterator it = nameResBuffs.mappings.begin(); it != nameResBuffs.mappings.end(); ++it) { // write the name length ch = it -> first.length(); if ((ret = socket_write(fd, (char *) &ch, 1, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 1) { cerr << "socket_write() timeout." << endl; return -1; } // write the name if ((ret = socket_write(fd, it -> first.c_str(), it -> first.length(), queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != it -> first.length()) { cerr << "socket_write() timeout." << endl; return -1; } // write the ip tmpIP = htonl(it -> second); if ((ret = socket_write(fd, (char *) &tmpIP, 4, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 4) { cerr << "socket_write() timeout." << endl; return -1; } } break; case 5: // getResolvedIPs if (len != 2) { return -1; } nameResBuffs.ips.clear(); nameResMan.getResolvedIPs(nameResBuffs.ips, stype); // write the number of ips... assert(nameResBuffs.ips.size() <= 0xffffffff); count32 = nameResBuffs.ips.size(); count32 = htonl(count32); if ((ret = socket_write(fd, (char *) &count32, sizeof(count32), queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != sizeof(count32)) { cerr << "socket_write() timeout." << endl; return -1; } // write the ips for (IPSet::iterator it = nameResBuffs.ips.begin(); it != nameResBuffs.ips.end(); ++it) { tmpIP = htonl(*it); if ((ret = socket_write(fd, (char *) &tmpIP, 4, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 4) { cerr << "socket_write() timeout." << endl; return -1; } } break; case 6: // hasHostResolvedIP if (len != 2 + 4 + 4 + 8) { return -1; } ch = (nameResMan.hasHostResolvedIP(ntohl(*(uint32_t *) (buf + 2)), ntohl(*(uint32_t *) (buf + 6)), TimeStamp(ntohl(*(uint32_t *) (buf + 10)), ntohl(*(uint32_t *) (buf + 14))), stype))?1:0; if ((ret = socket_write(fd, (char *) &ch, 1, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 1) { cerr << "socket_write() timeout." << endl; return -1; } break; case 7: // getLastResolutionTime if (len != 2 + 4 + 4 + 8) { return -1; } t = nameResMan.getLastResolutionTime(ntohl(*(uint32_t *) (buf + 2)), ntohl(*(uint32_t *) (buf + 6)), TimeStamp(ntohl(*(uint32_t *) (buf + 10)), ntohl(*(uint32_t *) (buf + 14))), stype); t.set(ntohl(t.seconds()), ntohl(t.microseconds())); if ((ret = socket_write(fd, (char *) &t, sizeof(t), queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != sizeof(t)) { cerr << "socket_write() timeout." << endl; return -1; } break; case -1: // clear if (len != 2) { // return error return -1; } nameResMan.clear(stype); ch = 0; if ((ret = socket_write(fd, (char *) &ch, 1, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 1) { cerr << "socket_write() timeout." << endl; return -1; } break; case -2: // load // load specific name resolution data if (len != 18) { // return error return -1; } begin.set(ntohl(*reinterpret_cast<uint32_t*>(buf + 2)), ntohl(*reinterpret_cast<uint32_t*>(buf + 6))); end.set(ntohl(*reinterpret_cast<uint32_t*>(buf + 10)), ntohl(*reinterpret_cast<uint32_t*>(buf + 14))); pthread_mutex_lock(&dnsUpdatesLock); dnsUpdates.push(make_pair(begin, end)); pthread_cond_signal(&dnsUpdatesCondition); pthread_mutex_unlock(&dnsUpdatesLock); ch = 0; if ((ret = socket_write(fd, (char *) &ch, 1, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 1) { cerr << "socket_write() timeout." << endl; return -1; } break; case -3: // waitForData // wait for all data to be loaded. if (len != 2) { // return error return -1; } timespec ts; ts.tv_sec = time(NULL) + static_cast <time_t>(queryManConfig.sockTimeout / 2); // heartbeat every queryManConfig.sockTimeout / 2 ts.tv_nsec = 0; pthread_mutex_lock(&dnsUpdatesLock); while (!dnsUpdates.empty()) { if (pthread_cond_timedwait(&dnsLoadedCondition, &dnsUpdatesLock, &ts) == ETIMEDOUT) { ch = 0; if ((ret = socket_write(fd, (char *) &ch, 1, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 1) { cerr << "socket_write() timeout." << endl; return -1; } ts.tv_sec = time(NULL) + static_cast <time_t>(queryManConfig.sockTimeout / 2); // heartbeat every queryManConfig.sockTimeout / 2 } } pthread_mutex_unlock(&dnsUpdatesLock); ch = 1; if ((ret = socket_write(fd, (char *) &ch, 1, queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != 1) { cerr << "socket_write() timeout." << endl; return -1; } break; case -4: // getConfig if (len != 2) { // return error return -1; } // write number of dbHomes... assert(queryManConfig.dbHomes.size() <= 0xffffffff); count32 = queryManConfig.dbHomes.size(); count32 = htonl(count32); if ((ret = socket_write(fd, (char *) &count32, sizeof(count32), queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != sizeof(count32)) { cerr << "socket_write() timeout." << endl; return -1; } // for each dbHome... for (vector <string>::iterator it = queryManConfig.dbHomes.begin(); it != queryManConfig.dbHomes.end(); ++it) { // write dbHome.size() assert(it -> size() <= 0xffffffff); count32 = it -> size(); count32 = htonl(count32); if ((ret = socket_write(fd, (char *) &count32, sizeof(count32), queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != sizeof(count32)) { cerr << "socket_write() timeout." << endl; return -1; } // write dbHome if ((ret = socket_write(fd, it -> c_str(), it -> size(), queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != it -> size()) { cerr << "socket_write() timeout." << endl; return -1; } } // write queryManConfig.sockPath.size() assert(queryManConfig.sockPath.size() <= 0xffffffff); count32 = queryManConfig.sockPath.size(); count32 = htonl(count32); if ((ret = socket_write(fd, (char *) &count32, sizeof(count32), queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != sizeof(count32)) { cerr << "socket_write() timeout." << endl; return -1; } // write queryManConfig.sockPath if ((ret = socket_write(fd, queryManConfig.sockPath.c_str(), queryManConfig.sockPath.size(), queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != queryManConfig.sockPath.size()) { cerr << "socket_write() timeout." << endl; return -1; } // write queryManConfig.sockTimeout tmpIP = static_cast <uint32_t> (queryManConfig.sockTimeout); tmpIP = htonl(tmpIP); if ((ret = socket_write(fd, (char *) &tmpIP, sizeof(tmpIP), queryManConfig.sockTimeout)) == -1) { // Error cerr << "socket_write() returned -1." << endl; return -1; } else if (ret != sizeof(tmpIP)) { cerr << "socket_write() timeout." << endl; return -1; } break; default: // unknown command...return error cerr << "processNameResCmd(): Unknown command!" << endl; return -1; }; return 0; }