bool isLocalAddress(const Poco::Net::SocketAddress & address, UInt16 clickhouse_port) { static auto interfaces = Poco::Net::NetworkInterface::list(); if (clickhouse_port == address.port()) { return interfaces.end() != std::find_if(interfaces.begin(), interfaces.end(), [&] (const Poco::Net::NetworkInterface & interface) { /** Compare the addresses without taking into account `scope`. * Theoretically, this may not be correct - depends on `route` setting * - through which interface we will actually access the specified address. */ return interface.address().length() == address.host().length() && 0 == memcmp(interface.address().addr(), address.host().addr(), address.host().length()); }); } return false; }
void NetworkListenTask::run() { Poco::Net::SocketAddress incomingAddress; TaskState lState; char* buffer; int receivedSize; // Create the receive buffer buffer = new char[Constants::NETWORK_RECEIVE_BUFFER_SIZE]; // A loop that receives network messages. The loop checks the state of this task in // a thread safe manner, and terminates if the the state is TS_KILLED. If the state is TS_SUSPEND // the loop does not receive any messages. for (lState = getState(); lState != TS_KILLED; lState = getState()) { if (lState == TS_SUSPENDED) { this->sleep(1); // Immediately continue to the next iteration if the the task is suspended continue; } try { // Listen for incoming messages receivedSize = mListenSocket.receiveFrom(buffer, Constants::NETWORK_RECEIVE_BUFFER_SIZE, incomingAddress); // If we received a message, send it to our NetworkListenBehaviour instance for processing if (receivedSize > 0) { LOG_DEBUG(EngineLog::LM_INFO_ENGINE, "NetworkListenTask::run(): Received message from: " << incomingAddress.toString()); // Lock for reading mListenBehaviour Poco::ScopedRWLock lock(rwLock, false); if (mListenBehaviour != NULL) { mListenBehaviour->processReceivedMessage(incomingAddress.host(), buffer, receivedSize); } else { LOG(EngineLog::LM_WARNING, "NetworkListenTask::run(): Received message dropped: there is no NetworkListenBehaviour instance available to process the message."); } } } catch (Exception& e) { LOG(EngineLog::LM_ERROR, "NetworkListenTask::run(): caught Exception: " << e.getMsg()); } catch (Poco::TimeoutException& e) { // ignore the TimeoutException, it is thrown often in non-blocking mode } catch (Poco::Exception& e) { LOG(EngineLog::LM_ERROR, "NetworkListenTask::run(): caught Poco::Exception: " << e.displayText()); } this->sleep(1); } // Free the receive buffer delete[] buffer; }