-#include <unistd.h>
-#include "threadname.hh"
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
#include "remote_logger.hh"
+
+#include <unistd.h>
#include <sys/uio.h>
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+
+#include "threadname.hh"
+
#ifdef RECURSOR
#include "logger.hh"
#else /* !RECURSOR */
bool CircularWriteBuffer::hasRoomFor(const std::string& str) const
{
- if (d_buffer.size() + 2 + str.size() > d_buffer.capacity()) {
- return false;
- }
-
- return true;
+ return d_buffer.size() + 2 + str.size() <= d_buffer.capacity();
}
bool CircularWriteBuffer::write(const std::string& str)
}
uint16_t len = htons(str.size());
- const char* ptr = reinterpret_cast<const char*>(&len);
- d_buffer.insert(d_buffer.end(), ptr, ptr + 2);
+ const char* ptr = reinterpret_cast<const char*>(&len); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
+ d_buffer.insert(d_buffer.end(), ptr, ptr + sizeof(len)); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
d_buffer.insert(d_buffer.end(), str.begin(), str.end());
return true;
}
-bool CircularWriteBuffer::flush(int fd)
+bool CircularWriteBuffer::flush(int fileDesc)
{
if (d_buffer.empty()) {
// not optional, we report EOF otherwise
auto arr1 = d_buffer.array_one();
auto arr2 = d_buffer.array_two();
- struct iovec iov[2];
+ std::array<iovec,2> iov{};
int pos = 0;
for(const auto& arr : {arr1, arr2}) {
- if(arr.second) {
- iov[pos].iov_base = arr.first;
- iov[pos].iov_len = arr.second;
+ if (arr.second != 0) {
+ iov.at(pos).iov_base = arr.first;
+ iov.at(pos).iov_len = arr.second;
++pos;
}
}
ssize_t res = 0;
do {
- res = writev(fd, iov, pos);
+ res = ::writev(fileDesc, iov.data(), pos);
if (res < 0) {
if (errno == EINTR) {
d_buffer.clear();
throw std::runtime_error("Couldn't flush a thing: " + stringerror());
}
- else if (!res) {
+ if (res == 0) {
/* we can't be sure we haven't sent a partial message,
and we don't want to send the remaining part after reconnecting */
d_buffer.clear();
d_buffer.clear();
}
else {
- while (res--) {
+ while (res-- != 0) {
d_buffer.pop_front();
}
}
return true;
}
-const std::string& RemoteLoggerInterface::toErrorString(Result r)
+const std::string& RemoteLoggerInterface::toErrorString(Result result)
{
static const std::array<std::string,5> str = {
"Queued",
"Submiting to queue failed",
"?"
};
- auto i = static_cast<unsigned int>(r);
- return str[std::min(i, 4U)];
+ auto tmp = static_cast<unsigned int>(result);
+ return str.at(std::min(tmp, 4U));
}
RemoteLogger::RemoteLogger(const ComboAddress& remote, uint16_t timeout, uint64_t maxQueuedBytes, uint8_t reconnectWaitTime, bool asyncConnect): d_remote(remote), d_timeout(timeout), d_reconnectWaitTime(reconnectWaitTime), d_asyncConnect(asyncConnect), d_runtime({CircularWriteBuffer(maxQueuedBytes), nullptr})
reconnect();
}
}
-
- sleep(d_reconnectWaitTime);
+ std::this_thread::sleep_for(std::chrono::seconds(d_reconnectWaitTime));
}
}
catch (const std::exception& e)
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
-#ifdef HAVE_CONFIG_H
+
#include "config.h"
-#endif
#include <atomic>
-#include <queue>
#include <thread>
#include "iputils.hh"
-#include "circular_buffer.hh"
+#include "circular_buffer.hh" // Keep, despite what clang-tidy days
#include "lock.hh"
#include "sstuff.hh"
{
}
- bool hasRoomFor(const std::string& str) const;
+ [[nodiscard]] bool hasRoomFor(const std::string& str) const;
bool write(const std::string& str);
- bool flush(int fd);
+ bool flush(int fileDesc);
private:
boost::circular_buffer<char> d_buffer;
};
class RemoteLoggerInterface
{
public:
- enum class Result : uint8_t { Queued, PipeFull, TooLarge, OtherError };
- static const std::string& toErrorString(Result r);
+ enum class Result : uint8_t
+ {
+ Queued,
+ PipeFull,
+ TooLarge,
+ OtherError
+ };
+ static const std::string& toErrorString(Result result);
+
+ RemoteLoggerInterface() = default;
+ RemoteLoggerInterface(const RemoteLoggerInterface&) = delete;
+ RemoteLoggerInterface(RemoteLoggerInterface&&) = delete;
+ RemoteLoggerInterface& operator=(const RemoteLoggerInterface&) = delete;
+ RemoteLoggerInterface& operator=(RemoteLoggerInterface&&) = delete;
+ virtual ~RemoteLoggerInterface() = default;
- virtual ~RemoteLoggerInterface() {};
virtual Result queueData(const std::string& data) = 0;
[[nodiscard]] virtual std::string address() const = 0;
[[nodiscard]] virtual std::string toString() = 0;
[[nodiscard]] virtual std::string name() const = 0;
- bool logQueries(void) const { return d_logQueries; }
- bool logResponses(void) const { return d_logResponses; }
- bool logNODs(void) const { return d_logNODs; }
- bool logUDRs(void) const { return d_logUDRs; }
+ [[nodiscard]] bool logQueries() const { return d_logQueries; }
+ [[nodiscard]] bool logResponses() const { return d_logResponses; }
+ [[nodiscard]] bool logNODs() const { return d_logNODs; }
+ [[nodiscard]] bool logUDRs() const { return d_logUDRs; }
void setLogQueries(bool flag) { d_logQueries = flag; }
void setLogResponses(bool flag) { d_logResponses = flag; }
void setLogNODs(bool flag) { d_logNODs = flag; }
class RemoteLogger : public RemoteLoggerInterface
{
public:
- RemoteLogger(const ComboAddress& remote, uint16_t timeout=2,
- uint64_t maxQueuedBytes=100000,
- uint8_t reconnectWaitTime=1,
- bool asyncConnect=false);
- ~RemoteLogger();
+ RemoteLogger(const RemoteLogger&) = delete;
+ RemoteLogger(RemoteLogger&&) = delete;
+ RemoteLogger& operator=(const RemoteLogger&) = delete;
+ RemoteLogger& operator=(RemoteLogger&&) = delete;
+ RemoteLogger(const ComboAddress& remote, uint16_t timeout = 2,
+ uint64_t maxQueuedBytes = 100000,
+ uint8_t reconnectWaitTime = 1,
+ bool asyncConnect = false);
+ ~RemoteLogger() override;
std::string address() const override
{