forked from gigablast/open-source-search-engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Dns.h
241 lines (190 loc) · 7.09 KB
/
Dns.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
// Copyright Matt Wells Nov 2000
// . uses UDP only (we'll do the TCP part later)
// . derived from UdpServer
// . always sends lookup to fastest dns
// . periodically pings other servers
// . if our primary dns goes down it's speed will be changed in hostmap
// and we'll have a new primary
// . if a request times out we try the next dns
#ifndef _DNSSERVER_H_
#define _DNSSERVER_H_
#include "UdpServer.h"
#include "DnsProtocol.h"
#include "Hostdb.h"
#include "RdbCache.h"
#include "Conf.h"
#define MAX_DEPTH 18 // we can have a lot of CNAME aliases w/ akamai
#define MAX_DNS_IPS 32
#define MAX_TRIED_IPS 32 // stop after asking 32 nameservers, return timed out
#define LOOP_BUF_SIZE 26100
//#define LOOP_BUF_SIZE (64*1024)
// use a default of 1 day for both caches
#define DNS_CACHE_MAX_AGE 60*60*24
#define DNS_CACHE_MAX_AGE_LOCAL 60*60*24
// structure for TLD root name servers
typedef struct {
int32_t expiry;
int32_t numTLDIPs;
uint32_t TLDIP[MAX_DNS_IPS];
} TLDIPEntry;
class Dns;
struct DnsState {
key_t m_hostnameKey;
// key for lookup into s_dnsTable hash table
long long m_tableKey;
Dns *m_this ;
void *m_state ;
void (*m_callback) ( void *state , long ip ) ;
char m_freeit;
bool m_cacheNotFounds;
char m_hostname[128];
// . point to the replies received from dns servers
// . m_dnsNames[] should point into these reply buffers
//char *m_replyBufPtrs[6];
//long m_numReplies;
// we can do a recursion up to 5 levels deep. sometimes the reply
// we get back is a list of ips of nameservers we need to ask.
// that can happen a few times in a row, and we have to keep track
// of the depth here. initially we set these ips to those of the
// root servers (or sometimes the local bind servers).
bool m_rootTLD [MAX_DEPTH];
long m_fallbacks[MAX_DEPTH];
long m_dnsIps [MAX_DEPTH][MAX_DNS_IPS];
long m_numDnsIps[MAX_DEPTH];
long m_depth; // current depth
// . use these nameservers to do the lookup
// . if not provided, they default to the root nameservers
// . the first one we ask is based on hash of hostname % m_numDns,
// if that times out, the 2nd is right after the first, etc. so we
// always stay in order.
// . m_dnsNames point into m_nameBuf, m_namePtr pts to the end of
// m_nameBuf so you can add new names to it.
// m_dnsNames are NULLified when getIPOfDNS() get their ip address
// which is then added to m_dnsIps[]
char *m_dnsNames [MAX_DEPTH][MAX_DNS_IPS];
long m_numDnsNames [MAX_DEPTH];
char m_nameBuf [512];
char *m_nameBufPtr;
char *m_nameBufEnd;
// this holds the one and only dns request
char m_request[512];
long m_requestSize;
// after we send to a nameserver add its ip to this list so we don't
// send to it again. or so we do not even add it to m_dnsIps again.
long m_triedIps[MAX_TRIED_IPS];
long m_numTried;
// if we have to get the ip of the dns, then we get back more dns
// that refer to that dns and we have to get the ip of those, ... etc.
// for getting the ip of a dns we cast m_buf as a DnsState and use
// that to avoid having to allocate more memory. however, we have to
// keep track of how many times we do that recursively until we run
// out of m_buf.
long m_loopCount;
// set to EDNSDEAD (hostname does not exist) if we encounter that
// error, however, we continue to ask other dns servers about the
// hostname because we can often uncover the ip address that way.
// but if we never do, we want to return this error, not ETIMEDOUT.
long m_errno;
// we have to turn it off in some requests for some reason
// like for www.fsis.usda.gov, othewise we get a refused to talk error
char m_recursionDesired;
// have a total timeout function
long m_startTime;
char m_buf [ LOOP_BUF_SIZE ];
};
// this is for storing callbacks. need to keep a queue of ppl waiting for
// the ip of the same hostname so we don't send dup requests to the same
// dns server.
class CallbackEntry {
public:
void *m_state;
void (* m_callback ) ( void *state , long ip );
class DnsState *m_ds;
//class CallbackEntry *m_next;
// we can't use a data ptr because slots get moved around when one
// is deleted.
long long m_nextKey;
// debug info
long m_listSize;
long m_listId;
};
class Dns {
public:
Dns();
// reset the udp server and rdb cache
void reset();
// . we create our own udpServer in here since we can't share that
// because of the protocol differences
// . read our dns servers from the conf file
bool init ( unsigned short clientPort );
// . check errno to on return or on callback to ensure no error
// . we set ip to 0 if not found
// . returns -1 and sets errno on error
// . returns 0 if transaction blocked, 1 if completed
bool getIp ( char *hostname ,
long hostnameLen ,
long *ip ,
void *state ,
void (* callback) ( void *state , long ip ) ,
DnsState *ds = NULL ,
//char *dnsNames = NULL ,
//long *numDnsNames = 0 ,
//long *dnsIps = NULL ,
//long numDnsIps = 0 ,
long timeout = 60 ,
bool dnsLookup = false ,
// monitor.cpp passes in false for this:
bool cacheNotFounds = true );
bool sendToNextDNS ( class DnsState *ds , long timeout = 60 ) ;
bool getIpOfDNS ( DnsState *ds ) ;
// . returns the ip
// . called to parse the ip out of the reply in "slot"
// . must be public so gotIpWrapper() can call it
// . also update the timestamps in our private hostmap
// . returns -1 on error
// . returns 0 if ip does not exist
long gotIp ( UdpSlot *slot , class DnsState *dnsState );
// . we have our own udp server
// . it contains our HostMap and DnsProtocol ptrs
// . keep public so gotIpWrapper() can use it to destroy the slot
UdpServer m_udpServer;
RdbCache *getCache () { return &m_rdbCache; };
RdbCache *getCacheLocal () { return &m_rdbCacheLocal; };
// . pull the hostname out of a dns reply packet's query resource rec.
bool extractHostname ( char *dgram ,
char *record ,
char *hostname );
void cancel ( void *state ) { m_udpServer.cancel ( state , -1 ); }
// returns true if in cache, and sets *ip
bool isInCache (key_t key , long *ip );
// add this hostnamekey/ip pair to the cache
void addToCache ( key_t hostnameKey , long ip , long ttl = -1 ) ;
// is it in the /etc/hosts file?
bool isInFile (key_t key , long *ip );
key_t getKey ( char *hostname , long hostnameLen ) ;
Host *getResponsibleHost ( key_t key ) ;
private:
bool loadFile ( );
//unsigned short m_dnsTransId;
// . key is a hash of hostname
// . record/slot contains a 4 byte ip entry (if in key is in cache)
// . cache is shared with other dbs
RdbCache m_rdbCache;
RdbCache m_rdbCacheLocal;
DnsProtocol m_proto;
short m_dnsClientPort;
//char *m_dnsDir;
long m_dnsIp;
short m_dnsPort; // we talk to dns thru this port
long m_numBind9Dns;
// /etc/hosts in hashed into this table
long *m_ips;
key_t *m_keys;
long m_numSlots;
};
//This stores the ip's for the machine where
//hash96(hostname) % g_hostdb.m_numHosts = cluster(group)
extern class Dns g_dns;
//This is MsgC's local machine cache
//extern class Dns g_dnsLocal;
#endif