]>
Commit | Line | Data |
---|---|---|
12c86877 BH |
1 | /* |
2 | PowerDNS Versatile Database Driven Nameserver | |
84f3c217 | 3 | Copyright (C) 2002-2010 PowerDNS.COM BV |
12c86877 BH |
4 | |
5 | This program is free software; you can redistribute it and/or modify | |
22dc646a BH |
6 | it under the terms of the GNU General Public License version 2 |
7 | as published by the Free Software Foundation | |
8 | ||
12c86877 BH |
9 | |
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with this program; if not, write to the Free Software | |
06bd9ccf | 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
12c86877 BH |
18 | */ |
19 | #ifndef PDNS_COMMUNICATOR_HH | |
20 | #define PDNS_COMMUNICATOR_HH | |
21 | ||
22 | #include <pthread.h> | |
23 | #include <string> | |
24 | #include <semaphore.h> | |
25 | #include <queue> | |
26 | #include <list> | |
f1a8bee5 | 27 | #include <limits> |
84f3c217 BH |
28 | #include <boost/multi_index_container.hpp> |
29 | #include <boost/multi_index/identity.hpp> | |
30 | #include <boost/multi_index/sequenced_index.hpp> | |
31 | using namespace boost::multi_index; | |
1258abe0 BH |
32 | |
33 | #ifndef WIN32 | |
34 | # include <unistd.h> | |
35 | # include <fcntl.h> | |
36 | # include <netdb.h> | |
37 | #endif // WIN32 | |
38 | ||
12c86877 BH |
39 | #include "lock.hh" |
40 | #include "packethandler.hh" | |
41 | ||
42 | using namespace std; | |
43 | ||
44 | struct SuckRequest | |
45 | { | |
46 | string domain; | |
47 | string master; | |
84f3c217 BH |
48 | bool operator<(const SuckRequest& b) const |
49 | { | |
50 | return tie(domain, master) < tie(b.domain, b.master); | |
51 | } | |
12c86877 BH |
52 | }; |
53 | ||
84f3c217 BH |
54 | typedef multi_index_container< |
55 | SuckRequest, | |
56 | indexed_by< | |
57 | sequenced<>, | |
58 | ordered_unique<identity<SuckRequest> > | |
59 | > | |
60 | > UniQueue; | |
61 | ||
12c86877 BH |
62 | class NotificationQueue |
63 | { | |
64 | public: | |
65 | void add(const string &domain, const string &ip) | |
66 | { | |
1258abe0 BH |
67 | NotificationRequest nr; |
68 | nr.domain = domain; | |
69 | nr.ip = ip; | |
70 | nr.attempts = 0; | |
71 | nr.id = Utility::random()%0xffff; | |
72 | nr.next = time(0); | |
12c86877 BH |
73 | |
74 | d_nqueue.push_back(nr); | |
75 | } | |
76 | ||
092f210a | 77 | bool removeIf(const string &remote, uint16_t id, const string &domain) |
12c86877 BH |
78 | { |
79 | for(d_nqueue_t::iterator i=d_nqueue.begin();i!=d_nqueue.end();++i) { | |
20ca8e7d BH |
80 | // cout<<i->id<<" "<<id<<endl; |
81 | //cout<<i->ip<<" "<<remote<<endl; | |
82 | //cout<<i->domain<<" "<<domain<<endl; | |
12c86877 BH |
83 | |
84 | if(i->id==id && i->ip==remote && i->domain==domain) { | |
57025e6a BH |
85 | d_nqueue.erase(i); |
86 | return true; | |
12c86877 BH |
87 | } |
88 | } | |
89 | return false; | |
90 | } | |
91 | ||
092f210a | 92 | bool getOne(string &domain, string &ip, uint16_t *id, bool &purged) |
12c86877 BH |
93 | { |
94 | for(d_nqueue_t::iterator i=d_nqueue.begin();i!=d_nqueue.end();++i) | |
95 | if(i->next <= time(0)) { | |
57025e6a BH |
96 | i->attempts++; |
97 | purged=false; | |
98 | i->next=time(0)+1+(1<<i->attempts); | |
99 | domain=i->domain; | |
100 | ip=i->ip; | |
101 | *id=i->id; | |
102 | purged=false; | |
103 | if(i->attempts>4) { | |
104 | purged=true; | |
105 | d_nqueue.erase(i); | |
106 | } | |
107 | return true; | |
12c86877 BH |
108 | } |
109 | return false; | |
110 | } | |
111 | ||
112 | time_t earliest() | |
113 | { | |
f1a8bee5 | 114 | time_t early=numeric_limits<time_t>::max() - 1; |
12c86877 BH |
115 | for(d_nqueue_t::const_iterator i=d_nqueue.begin();i!=d_nqueue.end();++i) |
116 | early=min(early,i->next); | |
117 | return early-time(0); | |
118 | } | |
119 | ||
120 | private: | |
121 | struct NotificationRequest | |
122 | { | |
123 | string domain; | |
124 | string ip; | |
125 | int attempts; | |
092f210a | 126 | uint16_t id; |
12c86877 BH |
127 | time_t next; |
128 | }; | |
129 | ||
130 | typedef list<NotificationRequest>d_nqueue_t; | |
131 | d_nqueue_t d_nqueue; | |
132 | ||
133 | }; | |
134 | ||
135 | /** this class contains a thread that communicates with other nameserver and does housekeeping. | |
136 | Initially, it is notified only of zones that need to be pulled in because they have been updated. */ | |
137 | ||
138 | class CommunicatorClass | |
139 | { | |
140 | public: | |
141 | CommunicatorClass() | |
142 | { | |
143 | pthread_mutex_init(&d_lock,0); | |
144 | pthread_mutex_init(&d_holelock,0); | |
145 | // sem_init(&d_suck_sem,0,0); | |
146 | // sem_init(&d_any_sem,0,0); | |
147 | d_tickinterval=60; | |
bd11bd1d | 148 | d_masterschanged=d_slaveschanged=true; |
12c86877 | 149 | } |
88c0425a | 150 | time_t doNotifications(); |
12c86877 BH |
151 | void go() |
152 | { | |
153 | pthread_t tid; | |
154 | pthread_create(&tid,0,&launchhelper,this); | |
155 | } | |
156 | ||
157 | void drillHole(const string &domain, const string &ip); | |
158 | bool justNotified(const string &domain, const string &ip); | |
98e05fce | 159 | void addSuckRequest(const string &domain, const string &master, bool priority=false); |
12c86877 BH |
160 | void notify(const string &domain, const string &ip); |
161 | void mainloop(); | |
162 | static void *launchhelper(void *p) | |
163 | { | |
164 | static_cast<CommunicatorClass *>(p)->mainloop(); | |
165 | return 0; | |
166 | } | |
167 | bool notifyDomain(const string &domain); | |
168 | private: | |
169 | void makeNotifySocket(); | |
170 | void queueNotifyDomain(const string &domain, DNSBackend *B); | |
171 | int d_nsock; | |
172 | map<pair<string,string>,time_t>d_holes; | |
173 | pthread_mutex_t d_holelock; | |
174 | void suck(const string &domain, const string &remote); | |
175 | void slaveRefresh(PacketHandler *P); | |
176 | void masterUpdateCheck(PacketHandler *P); | |
177 | pthread_mutex_t d_lock; | |
84f3c217 BH |
178 | |
179 | UniQueue d_suckdomains; | |
180 | ||
98e05fce | 181 | bool d_havepriosuckrequest; |
12c86877 BH |
182 | Semaphore d_suck_sem; |
183 | Semaphore d_any_sem; | |
88c0425a | 184 | time_t d_tickinterval; |
12c86877 | 185 | NotificationQueue d_nq; |
bd11bd1d | 186 | bool d_masterschanged, d_slaveschanged; |
12c86877 BH |
187 | }; |
188 | ||
189 | #endif |