]>
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" | |
36 | #include "resolver.hh" | |
37 | #include "logger.hh" | |
38 | #include "dns.hh" | |
39 | #include "arguments.hh" | |
13597144 | 40 | #include "packetcache.hh" |
519f5484 | 41 | #include "threadname.hh" |
02b37061 | 42 | |
3e7dcee6 | 43 | // there can be MANY OF THESE |
dbcb3066 BH |
44 | void CommunicatorClass::retrievalLoopThread(void) |
45 | { | |
519f5484 | 46 | setThreadName("pdns/comm-retre"); |
dbcb3066 BH |
47 | for(;;) { |
48 | d_suck_sem.wait(); | |
49 | SuckRequest sr; | |
50 | { | |
0ddde5fb | 51 | std::lock_guard<std::mutex> l(d_lock); |
dbcb3066 | 52 | if(d_suckdomains.empty()) |
f2d26033 | 53 | continue; |
232f0877 | 54 | |
dbcb3066 | 55 | sr=d_suckdomains.front(); |
f4ce804f | 56 | d_suckdomains.pop_front(); |
dbcb3066 | 57 | } |
d3ee36f2 | 58 | suck(sr.domain, sr.master); |
dbcb3066 BH |
59 | } |
60 | } | |
61 | ||
e8940583 | 62 | void CommunicatorClass::loadArgsIntoSet(const char *listname, set<string> &listset) |
d702c27f RC |
63 | { |
64 | vector<string> parts; | |
65 | stringtok(parts, ::arg()[listname], ", \t"); | |
66 | for (vector<string>::const_iterator iter = parts.begin(); iter != parts.end(); ++iter) { | |
67 | try { | |
68 | ComboAddress caIp(*iter, 53); | |
69 | listset.insert(caIp.toStringWithPort()); | |
70 | } | |
71 | catch(PDNSException &e) { | |
e6a9dde5 | 72 | g_log<<Logger::Error<<"Unparseable IP in "<<listname<<". Error: "<<e.reason<<endl; |
5bd2ea7b | 73 | _exit(1); |
d702c27f RC |
74 | } |
75 | } | |
76 | } | |
77 | ||
dbcb3066 BH |
78 | void CommunicatorClass::go() |
79 | { | |
d207ad63 RK |
80 | try { |
81 | PacketHandler::s_allowNotifyFrom.toMasks(::arg()["allow-notify-from"] ); | |
82 | } | |
83 | catch(PDNSException &e) { | |
e6a9dde5 | 84 | g_log<<Logger::Error<<"Unparseable IP in allow-notify-from. Error: "<<e.reason<<endl; |
5bd2ea7b | 85 | _exit(1); |
d207ad63 RK |
86 | } |
87 | ||
0ddde5fb RG |
88 | std::thread mainT(std::bind(&CommunicatorClass::mainloop, this)); |
89 | mainT.detach(); | |
90 | ||
91 | for(int n=0; n < ::arg().asNum("retrieval-threads", 1); ++n) { | |
92 | std::thread retrieve(std::bind(&CommunicatorClass::retrievalLoopThread, this)); | |
93 | retrieve.detach(); | |
94 | } | |
dbcb3066 | 95 | |
68bb0e57 | 96 | d_preventSelfNotification = ::arg().mustDo("prevent-self-notification"); |
79a454ef KM |
97 | |
98 | try { | |
99 | d_onlyNotify.toMasks(::arg()["only-notify"]); | |
100 | } | |
101 | catch(PDNSException &e) { | |
e6a9dde5 | 102 | g_log<<Logger::Error<<"Unparseable IP in only-notify. Error: "<<e.reason<<endl; |
5bd2ea7b | 103 | _exit(1); |
79a454ef | 104 | } |
24d3239e | 105 | |
e8940583 | 106 | loadArgsIntoSet("also-notify", d_alsoNotify); |
dad0736b | 107 | |
e8940583 | 108 | loadArgsIntoSet("forward-notify", PacketHandler::s_forwardNotify); |
dbcb3066 | 109 | } |
12c86877 BH |
110 | |
111 | void CommunicatorClass::mainloop(void) | |
112 | { | |
113 | try { | |
519f5484 | 114 | setThreadName("pdns/comm-main"); |
12c86877 | 115 | signal(SIGPIPE,SIG_IGN); |
e6a9dde5 | 116 | g_log<<Logger::Error<<"Master/slave communicator launching"<<endl; |
12c86877 | 117 | PacketHandler P; |
379ab445 | 118 | d_tickinterval=::arg().asNum("slave-cycle-interval"); |
0c01dd7c | 119 | makeNotifySockets(); |
12c86877 | 120 | |
006adf32 OM |
121 | int rc; |
122 | time_t next, tick; | |
123 | ||
3e76cf5f | 124 | for(;;) { |
12c86877 BH |
125 | slaveRefresh(&P); |
126 | masterUpdateCheck(&P); | |
3497eb18 | 127 | tick=doNotifications(&P); // this processes any notification acknowledgements and actually send out our own notifications |
006adf32 OM |
128 | |
129 | tick = min (tick, d_tickinterval); | |
130 | ||
131 | next=time(0)+tick; | |
12c86877 | 132 | |
006adf32 OM |
133 | while(time(0) < next) { |
134 | rc=d_any_sem.tryWait(); | |
12c86877 | 135 | |
006adf32 | 136 | if(rc) { |
3e76cf5f | 137 | bool extraSlaveRefresh = false; |
006adf32 | 138 | Utility::sleep(1); |
3e76cf5f | 139 | { |
0ddde5fb | 140 | std::lock_guard<std::mutex> l(d_lock); |
3e76cf5f OM |
141 | if (d_tocheck.size()) |
142 | extraSlaveRefresh = true; | |
143 | } | |
144 | if (extraSlaveRefresh) | |
145 | slaveRefresh(&P); | |
146 | } | |
147 | else { | |
006adf32 OM |
148 | // eat up extra posts to avoid busy looping if many posts were done |
149 | while (d_any_sem.tryWait() == 0) { | |
150 | } | |
3e76cf5f OM |
151 | break; // something happened |
152 | } | |
153 | // this gets executed at least once every second | |
3497eb18 | 154 | doNotifications(&P); |
12c86877 BH |
155 | } |
156 | } | |
157 | } | |
3f81d239 | 158 | catch(PDNSException &ae) { |
e6a9dde5 | 159 | g_log<<Logger::Error<<"Exiting because communicator thread died with error: "<<ae.reason<<endl; |
ac2bb9e7 | 160 | Utility::sleep(1); |
5bd2ea7b | 161 | _exit(1); |
12c86877 | 162 | } |
0c70797e | 163 | catch(std::exception &e) { |
e6a9dde5 | 164 | g_log<<Logger::Error<<"Exiting because communicator thread died with STL error: "<<e.what()<<endl; |
5bd2ea7b | 165 | _exit(1); |
12c86877 BH |
166 | } |
167 | catch( ... ) | |
168 | { | |
e6a9dde5 | 169 | g_log << Logger::Error << "Exiting because communicator caught unknown exception." << endl; |
5bd2ea7b | 170 | _exit(1); |
12c86877 BH |
171 | } |
172 | } | |
173 |