]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/communicator.cc
Merge pull request #9099 from PowerDNS/omoerbeek-patch-1
[thirdparty/pdns.git] / pdns / communicator.cc
CommitLineData
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
44void 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 62void 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
78void 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
111void 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