/** * Start function */ void IpfixCsExporter::performStart() { writeFileHeader(); addToCurTime(&nextChunkTimeout, maxChunkBufferTime*1000); addToCurTime(&nextFileTimeout, maxFileCreationInterval*1000); registerTimeout(); }
/** * Creates an output file and writes the CS_Ipfix_file_header */ void IpfixCsExporter::writeFileHeader() { closeFile(); currentFileSize = sizeof(CS_IPFIX_MAGIC)+sizeof(Ipfix_basic_flow_sequence_chunk_header); time_t timestamp = time(0); tm *st = localtime(×tamp); struct stat sta; char prefix[512]; snprintf(prefix, ARRAY_SIZE(prefix), "%s%s%02d%02d%02d-%02d%02d", destinationPath.c_str(), filenamePrefix.c_str(), st->tm_year+1900,st->tm_mon+1,st->tm_mday,st->tm_hour,st->tm_min); uint32_t i = 1; while (i<0xFFFFFFFE) { snprintf(currentFilename, ARRAY_SIZE(currentFilename), "%s_%03d", prefix, i); errno = 0; if (stat(currentFilename,&sta) != 0) { if (errno != 2) { //check error code msg(MSG_ERROR, "IpfixCsExporter: stat() on filename %s returned with error %i (%s)", currentFilename, errno, strerror(errno)); } else { // errno==2 means there is no file present break; } } i++; } snprintf(currentTmpname, ARRAY_SIZE(currentTmpname), "%s/._%s%02d%02d%02d-%02d%02d_%03d.part", destinationPath.c_str(), filenamePrefix.c_str(), st->tm_year+1900,st->tm_mon+1,st->tm_mday,st->tm_hour,st->tm_min, i); if (i==0xFFFFFFFF) { THROWEXCEPTION("failed to determine index for filename postfix (i==0xFFFFFFFF). Something went terribly wrong ...."); } // fix: cs_export is too stupid to read incomplete file. Let's create a temporary file .... currentFile = fopen(currentTmpname, "wb"); if (currentFile == NULL) { THROWEXCEPTION("Could not open file for writing. Check permissions."); } if (fwrite(CS_IPFIX_MAGIC, sizeof(CS_IPFIX_MAGIC), 1, currentFile)==0){ THROWEXCEPTION("Could not write file header. Check disk space."); } //new Timeouts: addToCurTime(&nextChunkTimeout, maxChunkBufferTime*1000); addToCurTime(&nextFileTimeout, maxFileCreationInterval*1000); }
/** * Writes the content of chunkList to the output file */ void IpfixCsExporter::writeChunkList() { Ipfix_basic_flow_sequence_chunk_header csChunkHeader; csChunkHeader.ipfix_type = htons(0x0008); csChunkHeader.chunk_length = htonl(chunkListSize*sizeof(Ipfix_basic_flow)+4); csChunkHeader.flow_count = htonl(chunkListSize); if (fwrite(&csChunkHeader, sizeof(csChunkHeader), 1, currentFile)==0){ THROWEXCEPTION("Could not chunk header. Check disk space."); } msg(MSG_DEBUG, "IpfixCsExporter: writing %u records to disk", chunkListSize); while (!chunkList.empty()){ Ipfix_basic_flow* flow = chunkList.front(); if (fwrite(flow, sizeof(Ipfix_basic_flow), 1, currentFile)==0){ THROWEXCEPTION("Could not write basic flow data. Check disk space."); } chunkList.pop_front(); chunkListSize--; delete flow; } addToCurTime(&nextChunkTimeout, maxChunkBufferTime*1000); }
/** * registers timeout for function onTimeout in Timer * (used to send records which are cached) */ void IpfixNetflowExporter::registerTimeout() { if (timeoutRegistered) return; addToCurTime(&nextTimeout, recordCacheTimeout); timer->addTimeout(this, nextTimeout, NULL); timeoutRegistered = true; }
/** * Registers timeout for function onTimeout in Timer * to compute the criterias for every interval */ void P2PDetector::registerTimeout() { if (timeoutRegistered) return; addToCurTime(&nextTimeout, intLength*1000); timer->addTimeout(this, nextTimeout, NULL); timeoutRegistered = true; }
void IpfixCsExporter::onTimeout(void* dataPtr) { timeoutRegistered = false; struct timeval now; gettimeofday(&now, 0); //check if this is one of the desired timeouts if (nextFileTimeout.tv_sec <= now.tv_sec) { //close File, add new one writeChunkList(); writeFileHeader(); addToCurTime(&nextChunkTimeout, maxChunkBufferTime*1000); addToCurTime(&nextFileTimeout, maxFileCreationInterval*1000); } else if (nextChunkTimeout.tv_sec <= now.tv_sec) { writeChunkList(); addToCurTime(&nextChunkTimeout, maxChunkBufferTime*1000); } registerTimeout(); }
/** * sends records to the network * @param forcesend to send all records regardless how many were cached */ void IpfixNetflowExporter::sendRecords(bool forcesend) { if (recordCache.size() == 0) return; // we have a maximum of 30 data records in one packet if ((recordCache.size() >= 30) || forcesend) { sendPacket(); } // set next timeout addToCurTime(&nextTimeout, recordCacheTimeout); }
/** * thread which regularly scans hashtable for expired buckets/flows */ void BaseAggregator::exporterThread() { struct timeval inttimer; gettimeofday(&inttimer, 0); //struct timeval difftime; //REQUIRE(timeval_subtract(&difftime, &stoptime, &starttime) == 0); /*timespec req; req.tv_sec = pollInterval / 1000; req.tv_nsec = (pollInterval % 1000) * 1000;*/ registerCurrentThread(); msg(MSG_INFO, "Polling aggregator each %u msec", pollInterval); while (!exitFlag) { addToCurTime(&inttimer, pollInterval); struct timeval curtime; gettimeofday(&curtime, 0); struct timeval difftime; if (timeval_subtract(&difftime, &inttimer, &curtime)!=1) { // restart nanosleep with the remaining sleep time // if we got interrupted by a signal struct timespec ts; TIMEVAL_TO_TIMESPEC(&difftime, &ts); while (nanosleep(&ts, &ts) == -1 && errno == EINTR); } gettimeofday(&curtime, 0); msg(MSG_VDEBUG,"Aggregator: starting Export"); for (size_t i = 0; i < rules->count; i++) { rules->rule[i]->hashtable->expireFlows(); } struct timeval endtime; gettimeofday(&endtime, 0); timeval_subtract(&difftime, &endtime, &curtime); msg (MSG_VDEBUG,"Aggregator: export took %.03f secs", (float)difftime.tv_usec/1000000+difftime.tv_sec); } if (getShutdownProperly()) { for (size_t i = 0; i < rules->count; i++) { rules->rule[i]->hashtable->expireFlows(true); } } unregisterCurrentThread(); }
void DelayedDeleter::addCfgNode(CfgNode* node) { struct timespec deadline; #if defined(DEBUG) mutex.lock(); #endif addToCurTime(&deadline, wait_in_ms); timer.addTimeout(this, deadline, (void*)node); #if defined(DEBUG) list.push_back(node); mutex.unlock(); #endif }