]>
Commit | Line | Data |
---|---|---|
12471842 PL |
1 | /* |
2 | * This file is part of PowerDNS or dnsdist. | |
3 | * Copyright -- PowerDNS.COM B.V. and its contributors | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of version 2 of the GNU General Public License as | |
7 | * published by the Free Software Foundation. | |
8 | * | |
9 | * In addition, for the avoidance of any doubt, permission is granted to | |
10 | * link this program with OpenSSL and to (re)distribute the binaries | |
11 | * produced as the result of such linking. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
21 | */ | |
aa7929a3 | 22 | #pragma once |
8f2c7de9 | 23 | #ifdef HAVE_CONFIG_H |
aa7929a3 | 24 | #include "config.h" |
8f2c7de9 | 25 | #endif |
aa7929a3 RG |
26 | |
27 | #include <atomic> | |
28 | #include <condition_variable> | |
29 | #include <queue> | |
30 | #include <thread> | |
31 | ||
32 | #include "iputils.hh" | |
da71b63b | 33 | #include <boost/circular_buffer.hpp> |
34 | ||
35 | /* Writes can be submitted and they are atomically accepted. Either the whole write | |
36 | ends up in the buffer or nothing ends up in the buffer. | |
37 | In case nothing ends up in the buffer, an exception is thrown. | |
38 | Similarly, EOF leads to this treatment | |
39 | ||
40 | The filedescriptor can be in non-blocking mode. | |
41 | ||
42 | This class is not threadsafe. | |
43 | */ | |
44 | ||
45 | class CircularWriteBuffer | |
46 | { | |
47 | public: | |
48 | explicit CircularWriteBuffer(int fd, size_t size) : d_fd(fd), d_buffer(size) | |
49 | { | |
50 | } | |
51 | ||
52 | void write(const std::string& str); | |
53 | void flush(); | |
54 | private: | |
55 | int d_fd; | |
56 | boost::circular_buffer<char> d_buffer; | |
57 | }; | |
aa7929a3 | 58 | |
82a91ddf CH |
59 | class RemoteLoggerInterface |
60 | { | |
61 | public: | |
62 | virtual ~RemoteLoggerInterface() {}; | |
63 | virtual void queueData(const std::string& data) = 0; | |
a4fd2d2f | 64 | virtual std::string toString() const = 0; |
82a91ddf CH |
65 | }; |
66 | ||
da71b63b | 67 | /* Thread safe. Will connect asynchronously on request. |
68 | Runs a reconnection thread that also periodicall flushes. | |
69 | Note that the buffer only runs as long as there is a connection. | |
70 | If there is no connection we don't buffer a thing | |
71 | */ | |
82a91ddf | 72 | class RemoteLogger : public RemoteLoggerInterface |
aa7929a3 RG |
73 | { |
74 | public: | |
da71b63b | 75 | RemoteLogger(const ComboAddress& remote, uint16_t timeout=2, |
76 | uint64_t maxQueuedBytes=100000, | |
77 | uint8_t reconnectWaitTime=1, | |
78 | bool asyncConnect=false); | |
79 | ~RemoteLogger(); | |
80 | void queueData(const std::string& data) override; | |
81 | std::string toString() const override | |
aa7929a3 | 82 | { |
da71b63b | 83 | return d_remote.toStringWithPort(); |
aa7929a3 | 84 | } |
63341e8d RG |
85 | void stop() |
86 | { | |
87 | d_exiting = true; | |
88 | } | |
da71b63b | 89 | std::atomic<uint32_t> d_drops{0}; |
aa7929a3 RG |
90 | private: |
91 | bool reconnect(); | |
da71b63b | 92 | void maintenanceThread(); |
aa7929a3 | 93 | |
aa7929a3 | 94 | ComboAddress d_remote; |
da71b63b | 95 | uint64_t d_maxQueuedBytes; |
aa7929a3 | 96 | int d_socket{-1}; |
da71b63b | 97 | std::unique_ptr<CircularWriteBuffer> d_writer; |
aa7929a3 RG |
98 | uint16_t d_timeout; |
99 | uint8_t d_reconnectWaitTime; | |
aa7929a3 | 100 | std::atomic<bool> d_exiting{false}; |
da71b63b | 101 | |
7af84c28 RG |
102 | bool d_asyncConnect{false}; |
103 | std::thread d_thread; | |
da71b63b | 104 | std::mutex d_mutex; |
aa7929a3 | 105 | }; |