2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
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.
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.
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.
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.
28 #include <boost/utility.hpp>
30 #include "packetcache.hh"
32 #include "communicator.hh"
33 #include "dnsbackend.hh"
34 #include "ueberbackend.hh"
35 #include "packethandler.hh"
36 #include "resolver.hh"
39 #include "arguments.hh"
40 #include "packetcache.hh"
41 #include "threadname.hh"
43 // there can be MANY OF THESE
44 void CommunicatorClass::retrievalLoopThread(void)
46 setThreadName("pdns/comm-retre");
51 std::lock_guard
<std::mutex
> l(d_lock
);
52 if(d_suckdomains
.empty())
55 sr
=d_suckdomains
.front();
56 d_suckdomains
.pop_front();
58 suck(sr
.domain
, sr
.master
);
62 void CommunicatorClass::loadArgsIntoSet(const char *listname
, set
<string
> &listset
)
65 stringtok(parts
, ::arg()[listname
], ", \t");
66 for (vector
<string
>::const_iterator iter
= parts
.begin(); iter
!= parts
.end(); ++iter
) {
68 ComboAddress
caIp(*iter
, 53);
69 listset
.insert(caIp
.toStringWithPort());
71 catch(PDNSException
&e
) {
72 g_log
<<Logger::Error
<<"Unparseable IP in "<<listname
<<". Error: "<<e
.reason
<<endl
;
78 void CommunicatorClass::go()
81 PacketHandler::s_allowNotifyFrom
.toMasks(::arg()["allow-notify-from"] );
83 catch(PDNSException
&e
) {
84 g_log
<<Logger::Error
<<"Unparseable IP in allow-notify-from. Error: "<<e
.reason
<<endl
;
88 std::thread
mainT(std::bind(&CommunicatorClass::mainloop
, this));
91 for(int n
=0; n
< ::arg().asNum("retrieval-threads", 1); ++n
) {
92 std::thread
retrieve(std::bind(&CommunicatorClass::retrievalLoopThread
, this));
96 d_preventSelfNotification
= ::arg().mustDo("prevent-self-notification");
99 d_onlyNotify
.toMasks(::arg()["only-notify"]);
101 catch(PDNSException
&e
) {
102 g_log
<<Logger::Error
<<"Unparseable IP in only-notify. Error: "<<e
.reason
<<endl
;
106 loadArgsIntoSet("also-notify", d_alsoNotify
);
108 loadArgsIntoSet("forward-notify", PacketHandler::s_forwardNotify
);
111 void CommunicatorClass::mainloop(void)
114 setThreadName("pdns/comm-main");
115 signal(SIGPIPE
,SIG_IGN
);
116 g_log
<<Logger::Error
<<"Master/slave communicator launching"<<endl
;
118 d_tickinterval
=::arg().asNum("slave-cycle-interval");
126 masterUpdateCheck(&P
);
127 tick
=doNotifications(&P
); // this processes any notification acknowledgements and actually send out our own notifications
129 tick
= min (tick
, d_tickinterval
);
133 while(time(0) < next
) {
134 rc
=d_any_sem
.tryWait();
137 bool extraSlaveRefresh
= false;
140 std::lock_guard
<std::mutex
> l(d_lock
);
141 if (d_tocheck
.size())
142 extraSlaveRefresh
= true;
144 if (extraSlaveRefresh
)
148 // eat up extra posts to avoid busy looping if many posts were done
149 while (d_any_sem
.tryWait() == 0) {
151 break; // something happened
153 // this gets executed at least once every second
158 catch(PDNSException
&ae
) {
159 g_log
<<Logger::Error
<<"Exiting because communicator thread died with error: "<<ae
.reason
<<endl
;
163 catch(std::exception
&e
) {
164 g_log
<<Logger::Error
<<"Exiting because communicator thread died with STL error: "<<e
.what()<<endl
;
169 g_log
<< Logger::Error
<< "Exiting because communicator caught unknown exception." << endl
;