JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callFrame, JSScope* scope) { RELEASE_ASSERT(scope); JSGlobalObject* globalObject = scope->globalObject(); RELEASE_ASSERT(globalObject); ASSERT(&globalObject->vm() == &vm); JSObject* exception = 0; UnlinkedProgramCodeBlock* unlinkedCodeBlock = globalObject->createProgramCodeBlock(callFrame, this, &exception); if (exception) return exception; m_unlinkedProgramCodeBlock.set(vm, this, unlinkedCodeBlock); BatchedTransitionOptimizer optimizer(vm, globalObject); for (size_t i = 0, numberOfFunctions = unlinkedCodeBlock->numberOfFunctionDecls(); i < numberOfFunctions; ++i) { UnlinkedFunctionExecutable* unlinkedFunctionExecutable = unlinkedCodeBlock->functionDecl(i); ASSERT(!unlinkedFunctionExecutable->name().isEmpty()); globalObject->addFunction(callFrame, unlinkedFunctionExecutable->name()); if (vm.typeProfiler() || vm.controlFlowProfiler()) { vm.functionHasExecutedCache()->insertUnexecutedRange(sourceID(), unlinkedFunctionExecutable->typeProfilingStartOffset(), unlinkedFunctionExecutable->typeProfilingEndOffset()); } } const VariableEnvironment& variableDeclarations = unlinkedCodeBlock->variableDeclarations(); for (auto& entry : variableDeclarations) { ASSERT(entry.value.isVar()); globalObject->addVar(callFrame, Identifier::fromUid(&vm, entry.key.get())); } return 0; }
ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source) : ScriptExecutable(exec->vm().programExecutableStructure.get(), exec->vm(), source, false) { m_typeProfilingStartOffset = 0; m_typeProfilingEndOffset = source.length() - 1; if (exec->vm().typeProfiler() || exec->vm().controlFlowProfiler()) exec->vm().functionHasExecutedCache()->insertUnexecutedRange(sourceID(), m_typeProfilingStartOffset, m_typeProfilingEndOffset); }
ModuleProgramExecutable::ModuleProgramExecutable(ExecState* exec, const SourceCode& source) : ScriptExecutable(exec->vm().moduleProgramExecutableStructure.get(), exec->vm(), source, false, DerivedContextType::None, false, EvalContextType::None, NoIntrinsic) { m_typeProfilingStartOffset = 0; m_typeProfilingEndOffset = source.length() - 1; if (exec->vm().typeProfiler() || exec->vm().controlFlowProfiler()) exec->vm().functionHasExecutedCache()->insertUnexecutedRange(sourceID(), m_typeProfilingStartOffset, m_typeProfilingEndOffset); }
/** * specific listener function. This function is called by @c listenerThread() */ void IpfixRawdirReader::run() { boost::shared_array<uint8_t> data; boost::shared_ptr<IpfixRecord::SourceID> sourceID(new IpfixRecord::SourceID); while(!exitFlag) { if (dir_iterator == end_iterator) { msg(MSG_DEBUG, "No more packets in packet directory path, terminating listener thread"); break; } std::string fname = packet_directory_path+"/"+dir_iterator->leaf(); if (boost::filesystem::is_directory(*dir_iterator)) { msg(MSG_DEBUG, "Skipping directory \"%s\"", fname.c_str()); dir_iterator++; continue; } dir_iterator++; msg(MSG_DEBUG, "Trying to read packet from file \"%s\"", fname.c_str()); std::ifstream packetFile(fname.c_str(), std::ios::in | std::ios::binary); packetFile.seekg(0, std::ios::end); int n = packetFile.tellg(); packetFile.seekg(0, std::ios::beg); if (n > MAX_MSG_LEN) { msg(MSG_DEBUG, "File too big \"%s\"", fname.c_str()); continue; } data.reset(new uint8_t[MAX_MSG_LEN]); packetFile.read(reinterpret_cast<char*>(data.get()), n); if (packetFile.bad()) { msg(MSG_DEBUG, "could not read from packet file, terminating listener thread"); break; } packetFile.close(); uint32_t ip = 0x7F000001; // 127.0.0.1 memcpy(sourceID->exporterAddress.ip, &ip, 4); sourceID->exporterAddress.len = 4; for (std::list<IpfixPacketProcessor*>::iterator i = packetProcessors.begin(); i != packetProcessors.end(); ++i) { msg(MSG_DEBUG, "Data block starts with: %x %x %x %x", data[0], data[1], data[2], data[3]); (*i)->processPacket(data, n, sourceID); } //sleep(1); } }
JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callFrame, JSScope* scope) { RELEASE_ASSERT(scope); JSGlobalObject* globalObject = scope->globalObject(); RELEASE_ASSERT(globalObject); ASSERT(&globalObject->vm() == &vm); JSObject* exception = 0; UnlinkedProgramCodeBlock* unlinkedCodeBlock = globalObject->createProgramCodeBlock(callFrame, this, &exception); if (exception) return exception; m_unlinkedProgramCodeBlock.set(vm, this, unlinkedCodeBlock); BatchedTransitionOptimizer optimizer(vm, globalObject); const UnlinkedProgramCodeBlock::VariableDeclations& variableDeclarations = unlinkedCodeBlock->variableDeclarations(); const UnlinkedProgramCodeBlock::FunctionDeclations& functionDeclarations = unlinkedCodeBlock->functionDeclarations(); for (size_t i = 0; i < functionDeclarations.size(); ++i) { UnlinkedFunctionExecutable* unlinkedFunctionExecutable = functionDeclarations[i].second.get(); JSValue value = JSFunction::create(vm, unlinkedFunctionExecutable->link(vm, m_source, lineNo()), scope); globalObject->addFunction(callFrame, functionDeclarations[i].first, value); if (vm.typeProfiler()) { vm.typeProfiler()->functionHasExecutedCache()->insertUnexecutedRange(sourceID(), unlinkedFunctionExecutable->typeProfilingStartOffset(), unlinkedFunctionExecutable->typeProfilingEndOffset()); } } for (size_t i = 0; i < variableDeclarations.size(); ++i) { if (variableDeclarations[i].second & DeclarationStacks::IsConstant) globalObject->addConst(callFrame, variableDeclarations[i].first); else globalObject->addVar(callFrame, variableDeclarations[i].first); } return 0; }
/** * SCTP specific listener function. This function is called by @c listenerThread() */ void IpfixReceiverSctpIpV4::run() { struct sockaddr_in clientAddress; socklen_t clientAddressLen; clientAddressLen = sizeof(struct sockaddr_in); fd_set fd_array; //all active filedescriptors fd_set readfds; //parameter for for pselect int maxfd; int ret; int rfd; struct timespec timeOut; FD_ZERO(&fd_array); FD_SET(listen_socket, &fd_array); // add listensocket maxfd = listen_socket; /* set a 400ms time-out on the pselect */ timeOut.tv_sec = 0L; timeOut.tv_nsec = 400000000L; while(!exitFlag) { readfds = fd_array; // because select() changes readfds ret = pselect(maxfd + 1, &readfds, NULL, NULL, &timeOut, NULL); // check only for something to read if (ret == 0) { /* Timeout */ continue; } if ((ret == -1) && (errno == EINTR)) { /* There was a signal... ignore */ continue; } if (ret < 0) { msg(MSG_ERROR ,"select() returned with an error"); THROWEXCEPTION("IpfixReceiverSctpIpV4: terminating listener thread"); break; } // looking for a new client to connect at listen_socket if (FD_ISSET(listen_socket, &readfds)){ rfd = accept(listen_socket, (struct sockaddr*)&clientAddress, &clientAddressLen); if (rfd >= 0){ if (isHostAuthorized(&clientAddress.sin_addr, sizeof(clientAddress.sin_addr))) { FD_SET(rfd, &fd_array); // add new client to fd_array msg(MSG_DEBUG, "IpfixReceiverSctpIpV4: Client connected from %s:%d, FD=%d", inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port), rfd); if (rfd > maxfd){ maxfd = rfd; } } else { msg(MSG_DEBUG, "IpfixReceiverSctpIpV4: Connection from unwanted client %s:%d, FD=%d rejected.", inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port), rfd); close(rfd); } }else{ msg(MSG_ERROR ,"accept() in ipfixReceiver failed"); THROWEXCEPTION("IpfixReceiverSctpIpV4: unable to accept new connection"); } } // check all connected sockets for new available data for (rfd = listen_socket + 1; rfd <= maxfd; ++rfd) { if (FD_ISSET(rfd, &readfds)) { boost::shared_array<uint8_t> data(new uint8_t[MAX_MSG_LEN]); ret = recvfrom(rfd, data.get(), MAX_MSG_LEN, 0, (struct sockaddr*)&clientAddress, &clientAddressLen); if (ret < 0) { // error msg(MSG_ERROR, "IpfixReceiverSctpIpV4: Client error (%s), close connection.", inet_ntoa(clientAddress.sin_addr)); close(rfd); // we treat an error like a shut down, so overwrite return value to zero ret = 0; } // create sourceId boost::shared_ptr<IpfixRecord::SourceID> sourceID(new IpfixRecord::SourceID); memcpy(sourceID->exporterAddress.ip, &clientAddress.sin_addr.s_addr, 4); sourceID->exporterAddress.len = 4; sourceID->exporterPort = ntohs(clientAddress.sin_port); sourceID->protocol = IPFIX_protocolIdentifier_SCTP; sourceID->receiverPort = receiverPort; sourceID->fileDescriptor = rfd; // send packet to all packet processors mutex.lock(); for (std::list<IpfixPacketProcessor*>::iterator i = packetProcessors.begin(); i != packetProcessors.end(); ++i) { (*i)->processPacket(data, ret, sourceID); } mutex.unlock(); if (ret == 0) { // this was a shut down (or error) FD_CLR(rfd, &fd_array); // delete dead client msg(MSG_DEBUG, "IpfixReceiverSctpIpV4: Client %s disconnected", inet_ntoa(clientAddress.sin_addr)); } } } } msg(MSG_DEBUG, "IpfixReceiverSctpIpV4: Exiting"); }
JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callFrame, JSScope* scope) { auto throwScope = DECLARE_THROW_SCOPE(vm); RELEASE_ASSERT(scope); JSGlobalObject* globalObject = scope->globalObject(); RELEASE_ASSERT(globalObject); ASSERT(&globalObject->vm() == &vm); ParserError error; JSParserStrictMode strictMode = isStrictMode() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict; DebuggerMode debuggerMode = globalObject->hasInteractiveDebugger() ? DebuggerOn : DebuggerOff; UnlinkedProgramCodeBlock* unlinkedCodeBlock = vm.codeCache()->getUnlinkedProgramCodeBlock( vm, this, source(), strictMode, debuggerMode, error); if (globalObject->hasDebugger()) globalObject->debugger()->sourceParsed(callFrame, source().provider(), error.line(), error.message()); if (error.isValid()) return error.toErrorObject(globalObject, source()); JSValue nextPrototype = globalObject->getPrototypeDirect(); while (nextPrototype && nextPrototype.isObject()) { if (UNLIKELY(asObject(nextPrototype)->type() == ProxyObjectType)) { ExecState* exec = globalObject->globalExec(); return createTypeError(exec, ASCIILiteral("Proxy is not allowed in the global prototype chain.")); } nextPrototype = asObject(nextPrototype)->getPrototypeDirect(); } JSGlobalLexicalEnvironment* globalLexicalEnvironment = globalObject->globalLexicalEnvironment(); const VariableEnvironment& variableDeclarations = unlinkedCodeBlock->variableDeclarations(); const VariableEnvironment& lexicalDeclarations = unlinkedCodeBlock->lexicalDeclarations(); // The ES6 spec says that no vars/global properties/let/const can be duplicated in the global scope. // This carried out section 15.1.8 of the ES6 spec: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-globaldeclarationinstantiation { ExecState* exec = globalObject->globalExec(); // Check for intersection of "var" and "let"/"const"/"class" for (auto& entry : lexicalDeclarations) { if (variableDeclarations.contains(entry.key)) return createSyntaxError(exec, makeString("Can't create duplicate variable: '", String(entry.key.get()), "'")); } // Check if any new "let"/"const"/"class" will shadow any pre-existing global property names, or "var"/"let"/"const" variables. // It's an error to introduce a shadow. for (auto& entry : lexicalDeclarations) { bool hasProperty = globalObject->hasProperty(exec, entry.key.get()); RETURN_IF_EXCEPTION(throwScope, throwScope.exception()); if (hasProperty) { // The ES6 spec says that just RestrictedGlobalProperty can't be shadowed // This carried out section 8.1.1.4.14 of the ES6 spec: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-hasrestrictedglobalproperty PropertyDescriptor descriptor; globalObject->getOwnPropertyDescriptor(exec, entry.key.get(), descriptor); if (descriptor.value() != jsUndefined() && !descriptor.configurable()) return createSyntaxError(exec, makeString("Can't create duplicate variable that shadows a global property: '", String(entry.key.get()), "'")); } hasProperty = globalLexicalEnvironment->hasProperty(exec, entry.key.get()); RETURN_IF_EXCEPTION(throwScope, throwScope.exception()); if (hasProperty) { if (UNLIKELY(entry.value.isConst() && !vm.globalConstRedeclarationShouldThrow() && !isStrictMode())) { // We only allow "const" duplicate declarations under this setting. // For example, we don't "let" variables to be overridden by "const" variables. if (globalLexicalEnvironment->isConstVariable(entry.key.get())) continue; } return createSyntaxError(exec, makeString("Can't create duplicate variable: '", String(entry.key.get()), "'")); } } // Check if any new "var"s will shadow any previous "let"/"const"/"class" names. // It's an error to introduce a shadow. if (!globalLexicalEnvironment->isEmpty()) { for (auto& entry : variableDeclarations) { bool hasProperty = globalLexicalEnvironment->hasProperty(exec, entry.key.get()); RETURN_IF_EXCEPTION(throwScope, throwScope.exception()); if (hasProperty) return createSyntaxError(exec, makeString("Can't create duplicate variable: '", String(entry.key.get()), "'")); } } } m_unlinkedProgramCodeBlock.set(vm, this, unlinkedCodeBlock); BatchedTransitionOptimizer optimizer(vm, globalObject); for (size_t i = 0, numberOfFunctions = unlinkedCodeBlock->numberOfFunctionDecls(); i < numberOfFunctions; ++i) { UnlinkedFunctionExecutable* unlinkedFunctionExecutable = unlinkedCodeBlock->functionDecl(i); ASSERT(!unlinkedFunctionExecutable->name().isEmpty()); globalObject->addFunction(callFrame, unlinkedFunctionExecutable->name()); if (vm.typeProfiler() || vm.controlFlowProfiler()) { vm.functionHasExecutedCache()->insertUnexecutedRange(sourceID(), unlinkedFunctionExecutable->typeProfilingStartOffset(), unlinkedFunctionExecutable->typeProfilingEndOffset()); } } for (auto& entry : variableDeclarations) { ASSERT(entry.value.isVar()); globalObject->addVar(callFrame, Identifier::fromUid(&vm, entry.key.get())); ASSERT(!throwScope.exception()); } { JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast<JSGlobalLexicalEnvironment*>(globalObject->globalScope()); SymbolTable* symbolTable = globalLexicalEnvironment->symbolTable(); ConcurrentJSLocker locker(symbolTable->m_lock); for (auto& entry : lexicalDeclarations) { if (UNLIKELY(entry.value.isConst() && !vm.globalConstRedeclarationShouldThrow() && !isStrictMode())) { if (symbolTable->contains(locker, entry.key.get())) continue; } ScopeOffset offset = symbolTable->takeNextScopeOffset(locker); SymbolTableEntry newEntry(VarOffset(offset), entry.value.isConst() ? ReadOnly : 0); newEntry.prepareToWatch(); symbolTable->add(locker, entry.key.get(), newEntry); ScopeOffset offsetForAssert = globalLexicalEnvironment->addVariables(1, jsTDZValue()); RELEASE_ASSERT(offsetForAssert == offset); } } return nullptr; }
JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callFrame, JSScope* scope) { RELEASE_ASSERT(scope); JSGlobalObject* globalObject = scope->globalObject(); RELEASE_ASSERT(globalObject); ASSERT(&globalObject->vm() == &vm); JSObject* exception = 0; UnlinkedProgramCodeBlock* unlinkedCodeBlock = globalObject->createProgramCodeBlock(callFrame, this, &exception); if (exception) return exception; JSGlobalLexicalEnvironment* globalLexicalEnvironment = globalObject->globalLexicalEnvironment(); const VariableEnvironment& variableDeclarations = unlinkedCodeBlock->variableDeclarations(); const VariableEnvironment& lexicalDeclarations = unlinkedCodeBlock->lexicalDeclarations(); // The ES6 spec says that no vars/global properties/let/const can be duplicated in the global scope. // This carried out section 15.1.8 of the ES6 spec: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-globaldeclarationinstantiation { ExecState* exec = globalObject->globalExec(); // Check for intersection of "var" and "let"/"const"/"class" for (auto& entry : lexicalDeclarations) { if (variableDeclarations.contains(entry.key)) return createSyntaxError(exec, makeString("Can't create duplicate variable: '", String(entry.key.get()), "'")); } // Check if any new "let"/"const"/"class" will shadow any pre-existing global property names, or "var"/"let"/"const" variables. // It's an error to introduce a shadow. for (auto& entry : lexicalDeclarations) { if (globalObject->hasProperty(exec, entry.key.get())) return createSyntaxError(exec, makeString("Can't create duplicate variable that shadows a global property: '", String(entry.key.get()), "'")); if (globalLexicalEnvironment->hasProperty(exec, entry.key.get())) return createSyntaxError(exec, makeString("Can't create duplicate variable: '", String(entry.key.get()), "'")); } // Check if any new "var"s will shadow any previous "let"/"const"/"class" names. // It's an error to introduce a shadow. if (!globalLexicalEnvironment->isEmpty()) { for (auto& entry : variableDeclarations) { if (globalLexicalEnvironment->hasProperty(exec, entry.key.get())) return createSyntaxError(exec, makeString("Can't create duplicate variable: '", String(entry.key.get()), "'")); } } } m_unlinkedProgramCodeBlock.set(vm, this, unlinkedCodeBlock); BatchedTransitionOptimizer optimizer(vm, globalObject); for (size_t i = 0, numberOfFunctions = unlinkedCodeBlock->numberOfFunctionDecls(); i < numberOfFunctions; ++i) { UnlinkedFunctionExecutable* unlinkedFunctionExecutable = unlinkedCodeBlock->functionDecl(i); ASSERT(!unlinkedFunctionExecutable->name().isEmpty()); globalObject->addFunction(callFrame, unlinkedFunctionExecutable->name()); if (vm.typeProfiler() || vm.controlFlowProfiler()) { vm.functionHasExecutedCache()->insertUnexecutedRange(sourceID(), unlinkedFunctionExecutable->typeProfilingStartOffset(), unlinkedFunctionExecutable->typeProfilingEndOffset()); } } for (auto& entry : variableDeclarations) { ASSERT(entry.value.isVar()); globalObject->addVar(callFrame, Identifier::fromUid(&vm, entry.key.get())); } { JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast<JSGlobalLexicalEnvironment*>(globalObject->globalScope()); SymbolTable* symbolTable = globalLexicalEnvironment->symbolTable(); ConcurrentJITLocker locker(symbolTable->m_lock); for (auto& entry : lexicalDeclarations) { ScopeOffset offset = symbolTable->takeNextScopeOffset(locker); SymbolTableEntry newEntry(VarOffset(offset), entry.value.isConst() ? ReadOnly : 0); newEntry.prepareToWatch(); symbolTable->add(locker, entry.key.get(), newEntry); ScopeOffset offsetForAssert = globalLexicalEnvironment->addVariables(1, jsTDZValue()); RELEASE_ASSERT(offsetForAssert == offset); } } return 0; }
/** * specific listener function. This function is called by @c listenerThread() */ void IpfixReceiverFile::run() { boost::shared_array<uint8_t> data; boost::shared_ptr<IpfixRecord::SourceID> sourceID(new IpfixRecord::SourceID); struct timeval msg_first, real_start, msg_now, real_now, msg_delta, real_delta, sleep_time, tmp_delta; struct timespec wait_spec; bool first = true; int missing = 0; settimezero(&msg_first); settimezero(&real_delta); settimezero(&real_start); settimezero(&msg_delta); settimezero(&msg_now); settimezero(&tmp_delta); for(int filecount=from; filecount<=to && !exitFlag; filecount++){ ostringstream numberformat (ostringstream::out); numberformat.width(10); numberformat.fill('0'); numberformat << filecount; std::string packet_file_path = packet_file_directory + packet_file_basename + numberformat.str(); msg(MSG_DEBUG, "IpfixReceiverFile: Trying to read message from file \"%s\"", packet_file_path.c_str()); packetFile.open(packet_file_path.c_str(), std::ios::in | std::ios::binary); if (packetFile.fail()){ msg(MSG_FATAL, "Couldn't open inputfile %s", packet_file_path.c_str()); if (++missing > MAXMISSINGFILES){ msg(MSG_FATAL, "Couldn't open %d files in a row...terminating", MAXMISSINGFILES); break; } continue; } missing = 0; packetFile.seekg(0, std::ios::end); uint64_t end = packetFile.tellg(); packetFile.seekg(0, std::ios::beg); uint64_t idx = 0; while (idx<end && !exitFlag) { uint16_t n; packetFile.seekg(sizeof(uint16_t), std::ios::cur); /*version number offset*/ packetFile.read(reinterpret_cast<char*>(&n), sizeof(uint16_t)); n = ntohs(n); /*reset the filepointer to the begin of the message*/ packetFile.seekg(-(int)(sizeof(uint32_t)), std::ios::cur); if (n > MAX_MSG_LEN) { msg(MSG_ERROR, "IpfixReceiverFile: packet at idx=%u too big with n=%u in file \"%s\"", idx, n, packet_file_path.c_str()); continue; } data.reset(new uint8_t[MAX_MSG_LEN]); packetFile.read(reinterpret_cast<char*>(data.get()), n); idx += n; if (packetFile.bad()) { msg(MSG_ERROR, "IpfixReceiverFile: bad packet_file: %s", packet_file_path.c_str()); continue; } uint32_t ip = 0x7F000001; // 127.0.0.1 memcpy(sourceID->exporterAddress.ip, &ip, 4); sourceID->exporterAddress.len = 4; if (! ignore_timestamps){ uint32_t exporttime = (uint32_t) ((uint32_t)(0xff & data[4])<<24 | (uint32_t)(0xff & data[5])<<16 | (uint32_t)(0xff & data[6])<<8 | (uint32_t)(0xff & data[7])); if(gettimeofday(&real_now, NULL) != 0){ msg(MSG_FATAL, "Error gettimeofday: %s", strerror(errno)); msg(MSG_FATAL, "Ignoring timestamps!"); ignore_timestamps = true; first = true; } if (first){ first = false; msg_first.tv_sec = (time_t)exporttime; real_start.tv_sec = real_now.tv_sec; real_start.tv_usec = real_now.tv_usec; } else{ msg_now.tv_sec = (time_t)exporttime; msg(MSG_DEBUG, "Exporttime: %u", exporttime); //msg_delta.tv_sec = msg_now.tv_sec - msg_first.tv_sec; timersub(&msg_now, &msg_first, &msg_delta); //real_delta.tv_sec = real_now.tv_sec - real_start.tv_sec; timersub(&real_now, &real_start, &real_delta); if(stretchTimeInt != 1){ if(stretchTimeInt == 0) timermulfloat(&msg_delta, &tmp_delta, stretchTime); else timermul(&msg_delta, &tmp_delta, stretchTimeInt); } else{ tmp_delta.tv_sec = msg_delta.tv_sec; tmp_delta.tv_usec = msg_delta.tv_usec; } //if(real_delta.tv_sec < msg_delta.tv_sec) sleep(sleep_time.tv_sec); if(timercmp(&real_delta, &tmp_delta, <)){ //sleep_time.tv_sec = msg_delta.tv_sec - real_delta.tv_sec; timersub(&tmp_delta, &real_delta, &sleep_time); msg(MSG_DEBUG, "msg_delta: %06us %06uus | tmp_delta: %06us %06uus | " "real_delta: %06us %06uus | sleep_time: %06us %06uus", (uint32_t) msg_delta.tv_sec, (uint32_t) msg_delta.tv_usec, (uint32_t) tmp_delta.tv_sec, (uint32_t) tmp_delta.tv_usec, (uint32_t) real_delta.tv_sec, (uint32_t) real_delta.tv_usec, (uint32_t) sleep_time.tv_sec,(uint32_t) sleep_time.tv_usec); wait_spec.tv_sec = sleep_time.tv_sec; wait_spec.tv_nsec = sleep_time.tv_usec*1000; msg(MSG_DEBUG, "sleeping for: %06us %06uus", (uint32_t)sleep_time.tv_sec, (uint32_t)sleep_time.tv_usec); if(nanosleep(&wait_spec, NULL)){ msg(MSG_ERROR, "nanosleep returned non-zero value: %s", strerror(errno)); } } else{ msg(MSG_DEBUG, "Not sleeping"); } } } for (std::list<IpfixPacketProcessor*>::iterator i = packetProcessors.begin(); i != packetProcessors.end(); ++i) { DPRINTF("Data block starts with: %x %x %x %x", data[0], data[1], data[2], data[3]); (*i)->processPacket(data, n, sourceID); } }
/** * SCTP specific listener function. This function is called by @c listenerThread() */ void IpfixReceiverSctpIpV4::run() { struct sockaddr_in clientAddress; socklen_t clientAddressLen; clientAddressLen = sizeof(struct sockaddr_in); fd_set fd_array; //all active filedescriptors int maxfd; FD_ZERO(&fd_array); FD_SET(listen_socket, &fd_array); // add listensocket maxfd = listen_socket; fd_set readfds; int ret; int rfd; while(!exit) { readfds = fd_array; // because select() changes readfds ret = select(maxfd + 1, &readfds, NULL, NULL, NULL); // check only for something to read if ((ret == -1) && (errno == EINTR)) { /* There was a signal... ignore */ continue; } if (ret < 0) { msg(MSG_ERROR ,"select() returned with an error"); THROWEXCEPTION("IpfixReceiverSctpIpV4: terminating listener thread"); break; } // looking for a new client to connect at listen_socket if (FD_ISSET(listen_socket, &readfds)){ rfd = accept(listen_socket, (struct sockaddr*)&clientAddress, &clientAddressLen); if (rfd >= 0){ FD_SET(rfd, &fd_array); // add new client to fd_array msg(MSG_DEBUG, "IpfixReceiverSctpIpV4: Client connected from %s:%d, FD=%d", inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port), rfd); if (rfd > maxfd){ maxfd = rfd; } }else{ msg(MSG_ERROR ,"accept() in ipfixReceiver failed"); THROWEXCEPTION("IpfixReceiverSctpIpV4: unable to accept new connection"); } } // check all connected sockets for new available data for (rfd = listen_socket + 1; rfd <= maxfd; ++rfd) { if (FD_ISSET(rfd, &readfds)) { boost::shared_array<uint8_t> data(new uint8_t[MAX_MSG_LEN]); ret = recvfrom(rfd, data.get(), MAX_MSG_LEN, 0, (struct sockaddr*)&clientAddress, &clientAddressLen); if (ret == 0) { // shut down initiated FD_CLR(rfd, &fd_array); // delete dead client msg(MSG_DEBUG, "IpfixReceiverSctpIpV4: Client disconnected"); }else{ if (isHostAuthorized(&clientAddress.sin_addr, sizeof(clientAddress.sin_addr))) { boost::shared_ptr<IpfixRecord::SourceID> sourceID(new IpfixRecord::SourceID); memcpy(sourceID->exporterAddress.ip, &clientAddress.sin_addr.s_addr, 4); sourceID->exporterAddress.len = 4; sourceID->exporterPort = ntohs(clientAddress.sin_port); sourceID->protocol = IPFIX_protocolIdentifier_SCTP; sourceID->receiverPort = receiverPort; sourceID->fileDescriptor = rfd; pthread_mutex_lock(&mutex); for (std::list<IpfixPacketProcessor*>::iterator i = packetProcessors.begin(); i != packetProcessors.end(); ++i) { (*i)->processPacket(data, ret, sourceID); } pthread_mutex_unlock(&mutex); } else{ msg(MSG_DEBUG, "packet from unauthorized host %s discarded", inet_ntoa(clientAddress.sin_addr)); } } } } } }