]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/remote_logger.cc
dnsdist: create RemoteLoggers in client mode, but avoid connecting
[thirdparty/pdns.git] / pdns / remote_logger.cc
CommitLineData
aa7929a3 1#include <unistd.h>
aa7929a3 2#include "remote_logger.hh"
49cfc104 3#include "config.h"
4#ifdef PDNS_CONFIG_ARGS
5#include "logger.hh"
6#define WE_ARE_RECURSOR
7#else
8#include "dolog.hh"
9#endif
aa7929a3
RG
10
11bool RemoteLogger::reconnect()
12{
13 if (d_socket >= 0) {
14 close(d_socket);
754f300f 15 d_socket = -1;
aa7929a3 16 }
c2d1d4ba 17 d_connected = false;
aa7929a3
RG
18 try {
19 d_socket = SSocket(d_remote.sin4.sin_family, SOCK_STREAM, 0);
aa7929a3 20 setNonBlocking(d_socket);
51959320 21 SConnectWithTimeout(d_socket, d_remote, d_timeout);
aa7929a3
RG
22 }
23 catch(const std::exception& e) {
49cfc104 24#ifdef WE_ARE_RECURSOR
25 L<<Logger::Warning<<"Error connecting to remote logger "<<d_remote.toStringWithPort()<<": "<<e.what()<<std::endl;
26#else
27 warnlog("Error connecting to remote logger %s: %s", d_remote.toStringWithPort(), e.what());
28#endif
aa7929a3
RG
29 return false;
30 }
c2d1d4ba 31 d_connected = true;
aa7929a3
RG
32 return true;
33}
34
c2d1d4ba
RG
35void RemoteLogger::busyReconnectLoop()
36{
37 while (!reconnect()) {
38 sleep(d_reconnectWaitTime);
39 }
40}
41
aa7929a3
RG
42void RemoteLogger::worker()
43{
44 while(true) {
45 std::string data;
46 {
47 std::unique_lock<std::mutex> lock(d_writeMutex);
48 d_queueCond.wait(lock, [this]{return (!d_writeQueue.empty()) || d_exiting;});
49 if (d_exiting) {
50 return;
51 }
52 data = d_writeQueue.front();
53 d_writeQueue.pop();
54 }
55
c2d1d4ba
RG
56 if (!d_connected) {
57 busyReconnectLoop();
58 }
59
aa7929a3 60 try {
2c570263
RG
61 uint16_t len = static_cast<uint16_t>(data.length());
62 sendSizeAndMsgWithTimeout(d_socket, len, data.c_str(), static_cast<int>(d_timeout), nullptr, nullptr, 0, 0, 0);
aa7929a3
RG
63 }
64 catch(const std::runtime_error& e) {
49cfc104 65#ifdef WE_ARE_RECURSOR
66 L<<Logger::Info<<"Error sending data to remote logger "<<d_remote.toStringWithPort()<<": "<< e.what()<<endl;
67#else
68 vinfolog("Error sending data to remote logger (%s): %s", d_remote.toStringWithPort(), e.what());
69#endif
c2d1d4ba 70 busyReconnectLoop();
aa7929a3
RG
71 }
72 }
73}
74
75void RemoteLogger::queueData(const std::string& data)
76{
77 {
78 std::unique_lock<std::mutex> lock(d_writeMutex);
79 if (d_writeQueue.size() >= d_maxQueuedEntries) {
80 d_writeQueue.pop();
81 }
82 d_writeQueue.push(data);
83 }
84 d_queueCond.notify_one();
85}
86
7af84c28 87RemoteLogger::RemoteLogger(const ComboAddress& remote, uint16_t timeout, uint64_t maxQueuedEntries, uint8_t reconnectWaitTime, bool asyncConnect): d_remote(remote), d_maxQueuedEntries(maxQueuedEntries), d_timeout(timeout), d_reconnectWaitTime(reconnectWaitTime), d_asyncConnect(asyncConnect), d_thread(&RemoteLogger::worker, this)
aa7929a3 88{
7af84c28
RG
89 if (!d_asyncConnect) {
90 reconnect();
91 }
aa7929a3
RG
92}
93
94RemoteLogger::~RemoteLogger()
95{
96 d_exiting = true;
754f300f 97 if (d_socket >= 0) {
aa7929a3 98 close(d_socket);
754f300f 99 d_socket = -1;
c2d1d4ba 100 d_connected = false;
754f300f 101 }
12aff2e5 102 d_queueCond.notify_one();
aa7929a3
RG
103 d_thread.join();
104}