void IpfixPayloadWriter::onDataRecord(IpfixDataRecord* record) { // only treat non-Options Data Records (although we cannot be sure that there is a Flow inside) if((record->templateInfo->setId != TemplateInfo::NetflowTemplate) && (record->templateInfo->setId != TemplateInfo::IpfixTemplate) && (record->templateInfo->setId != TemplateInfo::IpfixDataTemplate)) { record->removeReference(); return; } // convert ipfixrecord to connection struct Connection* conn = new Connection(record); conn->swapIfNeeded(); bool inserted = false; if (!ignoreEmptyPayload || conn->srcPayloadLen>0 || conn->dstPayloadLen>0) { if (!ignoreIncompleteTCP || conn->protocol!=6 || ((conn->srcTcpControlBits&Connection::SYN)==Connection::SYN && ((conn->dstTcpControlBits&Connection::SYN)==Connection::SYN))) { // check if both directions have SYN flag set if (noConnections>0) { // insert entry into sorted list list<Connection*>::iterator iter = connections.begin(); uint32_t counter = 0; while (iter != connections.end() && counter<noConnections) { if ((*iter)->srcTimeStart>conn->srcTimeStart) { connections.insert(iter, conn); inserted = true; break; } counter++; iter++; } if ((!inserted) && (counter<noConnections)) { connections.push_back(conn); inserted = true; } } else { // write entry directly to filesystem dumpEntry(conn); } } else { statIncompleteTCPDropped++; } } else { statEmptyPayloadDropped++; } if (!inserted) delete conn; record->removeReference(); }
// From gdb: // (gdb) set language c++ // (gdb) call HPHP::Trace::dumpRingBuffer(100) // // or // // (gdb) call HPHP::Trace::dumpRingBufferMasked(100, // (1 << HPHP::Trace::RBTypeFuncEntry)) void dumpRingBufferMasked(int numEntries, uint32_t types) { int startIdx = (g_ringIdx - numEntries) % kMaxRBEntries; while (startIdx < 0) { startIdx += kMaxRBEntries; } ASSERT(startIdx >= 0 && startIdx < kMaxRBEntries); int numDumped = 0; for (int i = 0; i < kMaxRBEntries && numDumped < numEntries; i++) { RingBufferEntry* rb = &g_ring[(startIdx + i) % kMaxRBEntries]; if ((1 << rb->m_type) & types) { numDumped++; dumpEntry(rb); } } }
// From gdb: // (gdb) set language c++ // (gdb) call HPHP::Trace::dumpRingBuffer(100) // // or // // (gdb) call HPHP::Trace::dumpRingBufferMasked(100, // (1 << HPHP::Trace::RBTypeFuncEntry)) void dumpRingBufferMasked(int numEntries, uint32_t types, uint32_t threadId) { if (!g_ring_ptr) return; int startIdx = (g_ringIdx.load() - numEntries) % kMaxRBEntries; while (startIdx < 0) { startIdx += kMaxRBEntries; } assert(startIdx >= 0 && startIdx < kMaxRBEntries); int numDumped = 0; for (int i = 0; i < kMaxRBEntries && numDumped < numEntries; i++) { RingBufferEntry* rb = &g_ring_ptr[(startIdx + i) % kMaxRBEntries]; if ((1 << rb->m_type) & types && (!threadId || threadId == rb->m_threadId)) { numDumped++; dumpEntry(rb); } } }
void IpfixPayloadWriter::performShutdown() { if (noConnections==0) return; // write the first N entries in connection list to directory in files list<Connection*>::iterator iter = connections.begin(); while (iter!=connections.end()) { if (connectionID>=noConnections) break; Connection* conn = *iter; dumpEntry(conn); iter++; } // delete entries in list while (!connections.empty()) { Connection* c = connections.back(); delete c; connections.pop_back(); } return; }