]>
Commit | Line | Data |
---|---|---|
12c86877 | 1 | /* |
12471842 PL |
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 | */ | |
870a0fe4 AT |
22 | #ifdef HAVE_CONFIG_H |
23 | #include "config.h" | |
24 | #endif | |
0ddde5fb RG |
25 | |
26 | #include <set> | |
27 | #include <thread> | |
28 | #include <boost/utility.hpp> | |
29 | ||
379ab445 | 30 | #include "packetcache.hh" |
12c86877 | 31 | #include "utility.hh" |
12c86877 | 32 | #include "communicator.hh" |
12c86877 BH |
33 | #include "dnsbackend.hh" |
34 | #include "ueberbackend.hh" | |
35 | #include "packethandler.hh" | |
12c86877 BH |
36 | #include "logger.hh" |
37 | #include "dns.hh" | |
38 | #include "arguments.hh" | |
13597144 | 39 | #include "packetcache.hh" |
519f5484 | 40 | #include "threadname.hh" |
02b37061 | 41 | |
3e7dcee6 | 42 | // there can be MANY OF THESE |
e52fb6a4 | 43 | void CommunicatorClass::retrievalLoopThread() |
dbcb3066 | 44 | { |
519f5484 | 45 | setThreadName("pdns/comm-retre"); |
2dff6ed5 | 46 | for (;;) { |
dbcb3066 BH |
47 | d_suck_sem.wait(); |
48 | SuckRequest sr; | |
49 | { | |
01e96795 RG |
50 | auto data = d_data.lock(); |
51 | if (data->d_suckdomains.empty()) { | |
f2d26033 | 52 | continue; |
01e96795 | 53 | } |
6a401e76 | 54 | |
01e96795 | 55 | auto firstItem = data->d_suckdomains.begin(); |
2dff6ed5 CHB |
56 | |
57 | sr = *firstItem; | |
01e96795 RG |
58 | data->d_suckdomains.erase(firstItem); |
59 | if (data->d_suckdomains.empty()) { | |
60 | data->d_sorthelper = 0; | |
6a401e76 | 61 | } |
dbcb3066 | 62 | } |
d525b58b | 63 | suck(sr.domain, sr.primary, sr.force); |
dbcb3066 BH |
64 | } |
65 | } | |
66 | ||
2dff6ed5 | 67 | void CommunicatorClass::loadArgsIntoSet(const char* listname, set<string>& listset) |
d702c27f RC |
68 | { |
69 | vector<string> parts; | |
70 | stringtok(parts, ::arg()[listname], ", \t"); | |
2dff6ed5 | 71 | for (const auto& part : parts) { |
d702c27f | 72 | try { |
d7f67000 | 73 | ComboAddress caIp(part, 53); |
d702c27f RC |
74 | listset.insert(caIp.toStringWithPort()); |
75 | } | |
2dff6ed5 CHB |
76 | catch (PDNSException& e) { |
77 | g_log << Logger::Error << "Unparseable IP in " << listname << ". Error: " << e.reason << endl; | |
5bd2ea7b | 78 | _exit(1); |
d702c27f RC |
79 | } |
80 | } | |
81 | } | |
82 | ||
dbcb3066 BH |
83 | void CommunicatorClass::go() |
84 | { | |
d207ad63 | 85 | try { |
2dff6ed5 | 86 | PacketHandler::s_allowNotifyFrom.toMasks(::arg()["allow-notify-from"]); |
d207ad63 | 87 | } |
2dff6ed5 CHB |
88 | catch (PDNSException& e) { |
89 | g_log << Logger::Error << "Unparseable IP in allow-notify-from. Error: " << e.reason << endl; | |
5bd2ea7b | 90 | _exit(1); |
d207ad63 RK |
91 | } |
92 | ||
2dff6ed5 | 93 | std::thread mainT([this]() { mainloop(); }); |
0ddde5fb RG |
94 | mainT.detach(); |
95 | ||
937cd921 | 96 | for (int nthreads = 0; nthreads < ::arg().asNum("retrieval-threads", 1); ++nthreads) { |
2dff6ed5 | 97 | std::thread retrieve([this]() { retrievalLoopThread(); }); |
0ddde5fb RG |
98 | retrieve.detach(); |
99 | } | |
dbcb3066 | 100 | |
68bb0e57 | 101 | d_preventSelfNotification = ::arg().mustDo("prevent-self-notification"); |
7bd9b307 CHB |
102 | |
103 | auto delay = ::arg().asNum("delay-notifications"); | |
104 | if (delay > 0) { | |
105 | d_delayNotifications = static_cast<time_t>(delay); | |
106 | } | |
79a454ef KM |
107 | |
108 | try { | |
109 | d_onlyNotify.toMasks(::arg()["only-notify"]); | |
110 | } | |
2dff6ed5 CHB |
111 | catch (PDNSException& e) { |
112 | g_log << Logger::Error << "Unparseable IP in only-notify. Error: " << e.reason << endl; | |
5bd2ea7b | 113 | _exit(1); |
79a454ef | 114 | } |
24d3239e | 115 | |
e8940583 | 116 | loadArgsIntoSet("also-notify", d_alsoNotify); |
dad0736b | 117 | |
e8940583 | 118 | loadArgsIntoSet("forward-notify", PacketHandler::s_forwardNotify); |
dbcb3066 | 119 | } |
12c86877 | 120 | |
e52fb6a4 | 121 | void CommunicatorClass::mainloop() |
12c86877 BH |
122 | { |
123 | try { | |
519f5484 | 124 | setThreadName("pdns/comm-main"); |
2dff6ed5 | 125 | signal(SIGPIPE, SIG_IGN); |
a6075829 KM |
126 | g_log << Logger::Warning << "Primary/secondary communicator launching" << endl; |
127 | ||
128 | d_tickinterval = ::arg().asNum("xfr-cycle-interval"); | |
12c86877 | 129 | |
006adf32 | 130 | int rc; |
a6075829 KM |
131 | time_t next; |
132 | PacketHandler P; | |
133 | ||
134 | makeNotifySockets(); | |
006adf32 | 135 | |
2dff6ed5 | 136 | for (;;) { |
c02c999b | 137 | secondaryRefresh(&P); |
d525b58b | 138 | primaryUpdateCheck(&P); |
a6075829 KM |
139 | doNotifications(&P); // this processes any notification acknowledgements and actually send out our own notifications |
140 | ||
141 | next = time(nullptr) + d_tickinterval; | |
12c86877 | 142 | |
2dff6ed5 CHB |
143 | while (time(nullptr) < next) { |
144 | rc = d_any_sem.tryWait(); | |
12c86877 | 145 | |
937cd921 | 146 | if (rc != 0) { |
c02c999b | 147 | bool extraSecondaryRefresh = false; |
006adf32 | 148 | Utility::sleep(1); |
3e76cf5f | 149 | { |
01e96795 RG |
150 | auto data = d_data.lock(); |
151 | if (data->d_tocheck.size()) { | |
c02c999b | 152 | extraSecondaryRefresh = true; |
01e96795 | 153 | } |
3e76cf5f | 154 | } |
c02c999b KM |
155 | if (extraSecondaryRefresh) |
156 | secondaryRefresh(&P); | |
3e76cf5f OM |
157 | } |
158 | else { | |
006adf32 OM |
159 | // eat up extra posts to avoid busy looping if many posts were done |
160 | while (d_any_sem.tryWait() == 0) { | |
161 | } | |
3e76cf5f OM |
162 | break; // something happened |
163 | } | |
a6075829 | 164 | // this gets executed about once per second |
3497eb18 | 165 | doNotifications(&P); |
12c86877 BH |
166 | } |
167 | } | |
168 | } | |
2dff6ed5 CHB |
169 | catch (PDNSException& ae) { |
170 | g_log << Logger::Error << "Exiting because communicator thread died with error: " << ae.reason << endl; | |
ac2bb9e7 | 171 | Utility::sleep(1); |
5bd2ea7b | 172 | _exit(1); |
12c86877 | 173 | } |
2dff6ed5 CHB |
174 | catch (std::exception& e) { |
175 | g_log << Logger::Error << "Exiting because communicator thread died with STL error: " << e.what() << endl; | |
5bd2ea7b | 176 | _exit(1); |
12c86877 | 177 | } |
2dff6ed5 | 178 | catch (...) { |
e6a9dde5 | 179 | g_log << Logger::Error << "Exiting because communicator caught unknown exception." << endl; |
5bd2ea7b | 180 | _exit(1); |
12c86877 BH |
181 | } |
182 | } |