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.
25 #include "packetcache.hh"
28 #include "communicator.hh"
30 #include <boost/utility.hpp>
31 #include "dnsbackend.hh"
32 #include "ueberbackend.hh"
33 #include "packethandler.hh"
34 #include "resolver.hh"
37 #include "arguments.hh"
38 #include "packetcache.hh"
39 #include "threadname.hh"
41 // there can be MANY OF THESE
42 void CommunicatorClass::retrievalLoopThread(void)
44 setThreadName("pdns/comm-retre");
50 if(d_suckdomains
.empty())
53 sr
=d_suckdomains
.front();
54 d_suckdomains
.pop_front();
56 suck(sr
.domain
, sr
.master
);
60 void CommunicatorClass::loadArgsIntoSet(const char *listname
, set
<string
> &listset
)
63 stringtok(parts
, ::arg()[listname
], ", \t");
64 for (vector
<string
>::const_iterator iter
= parts
.begin(); iter
!= parts
.end(); ++iter
) {
66 ComboAddress
caIp(*iter
, 53);
67 listset
.insert(caIp
.toStringWithPort());
69 catch(PDNSException
&e
) {
70 g_log
<<Logger::Error
<<"Unparseable IP in "<<listname
<<". Error: "<<e
.reason
<<endl
;
76 void CommunicatorClass::go()
79 PacketHandler::s_allowNotifyFrom
.toMasks(::arg()["allow-notify-from"] );
81 catch(PDNSException
&e
) {
82 g_log
<<Logger::Error
<<"Unparseable IP in allow-notify-from. Error: "<<e
.reason
<<endl
;
87 pthread_create(&tid
,0,&launchhelper
,this); // Starts CommunicatorClass::mainloop()
88 for(int n
=0; n
< ::arg().asNum("retrieval-threads", 1); ++n
)
89 pthread_create(&tid
, 0, &retrieveLaunchhelper
, this); // Starts CommunicatorClass::retrievalLoopThread()
91 d_preventSelfNotification
= ::arg().mustDo("prevent-self-notification");
94 d_onlyNotify
.toMasks(::arg()["only-notify"]);
96 catch(PDNSException
&e
) {
97 g_log
<<Logger::Error
<<"Unparseable IP in only-notify. Error: "<<e
.reason
<<endl
;
101 loadArgsIntoSet("also-notify", d_alsoNotify
);
103 loadArgsIntoSet("forward-notify", PacketHandler::s_forwardNotify
);
106 void CommunicatorClass::mainloop(void)
109 setThreadName("pdns/comm-main");
110 signal(SIGPIPE
,SIG_IGN
);
111 g_log
<<Logger::Error
<<"Master/slave communicator launching"<<endl
;
113 d_tickinterval
=::arg().asNum("slave-cycle-interval");
121 masterUpdateCheck(&P
);
122 tick
=doNotifications(); // this processes any notification acknowledgements and actually send out our own notifications
124 tick
= min (tick
, d_tickinterval
);
128 while(time(0) < next
) {
129 rc
=d_any_sem
.tryWait();
132 bool extraSlaveRefresh
= false;
136 if (d_tocheck
.size())
137 extraSlaveRefresh
= true;
139 if (extraSlaveRefresh
)
143 // eat up extra posts to avoid busy looping if many posts were done
144 while (d_any_sem
.tryWait() == 0) {
146 break; // something happened
148 // this gets executed at least once every second
153 catch(PDNSException
&ae
) {
154 g_log
<<Logger::Error
<<"Exiting because communicator thread died with error: "<<ae
.reason
<<endl
;
158 catch(std::exception
&e
) {
159 g_log
<<Logger::Error
<<"Exiting because communicator thread died with STL error: "<<e
.what()<<endl
;
164 g_log
<< Logger::Error
<< "Exiting because communicator caught unknown exception." << endl
;