open-source-search-engine/Dns.h

242 lines
7.2 KiB
C
Raw Normal View History

2013-08-03 00:12:24 +04:00
// 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
2014-10-30 22:36:39 +03:00
int64_t m_tableKey;
2013-08-03 00:12:24 +04:00
Dns *m_this ;
void *m_state ;
2014-11-11 01:45:11 +03:00
void (*m_callback) ( void *state , int32_t ip ) ;
2013-08-03 00:12:24 +04:00
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];
2014-11-11 01:45:11 +03:00
//int32_t m_numReplies;
2013-08-03 00:12:24 +04:00
// 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];
2014-11-11 01:45:11 +03:00
int32_t m_fallbacks[MAX_DEPTH];
int32_t m_dnsIps [MAX_DEPTH][MAX_DNS_IPS];
int32_t m_numDnsIps[MAX_DEPTH];
int32_t m_depth; // current depth
2013-08-03 00:12:24 +04:00
// . 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];
2014-11-11 01:45:11 +03:00
int32_t m_numDnsNames [MAX_DEPTH];
2013-08-03 00:12:24 +04:00
char m_nameBuf [512];
char *m_nameBufPtr;
char *m_nameBufEnd;
// this holds the one and only dns request
char m_request[512];
2014-11-11 01:45:11 +03:00
int32_t m_requestSize;
2013-08-03 00:12:24 +04:00
// 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.
2014-11-11 01:45:11 +03:00
int32_t m_triedIps[MAX_TRIED_IPS];
int32_t m_numTried;
2013-08-03 00:12:24 +04:00
// 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.
2014-11-11 01:45:11 +03:00
int32_t m_loopCount;
2013-08-03 00:12:24 +04:00
// 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.
2014-11-11 01:45:11 +03:00
int32_t m_errno;
2013-08-03 00:12:24 +04:00
// 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
2014-11-11 01:45:11 +03:00
int32_t m_startTime;
2013-08-03 00:12:24 +04:00
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;
2014-11-11 01:45:11 +03:00
void (* m_callback ) ( void *state , int32_t ip );
struct DnsState *m_ds;
2013-08-03 00:12:24 +04:00
//class CallbackEntry *m_next;
// we can't use a data ptr because slots get moved around when one
// is deleted.
2014-10-30 22:36:39 +03:00
int64_t m_nextKey;
2013-08-03 00:12:24 +04:00
// debug info
2014-11-11 01:45:11 +03:00
int32_t m_listSize;
int32_t m_listId;
2013-08-03 00:12:24 +04:00
};
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
2014-11-11 01:45:11 +03:00
bool init ( uint16_t clientPort );
2013-08-03 00:12:24 +04:00
// . 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 ,
2014-11-11 01:45:11 +03:00
int32_t hostnameLen ,
int32_t *ip ,
2013-08-03 00:12:24 +04:00
void *state ,
2014-11-11 01:45:11 +03:00
void (* callback) ( void *state , int32_t ip ) ,
2013-08-03 00:12:24 +04:00
DnsState *ds = NULL ,
//char *dnsNames = NULL ,
2014-11-11 01:45:11 +03:00
//int32_t *numDnsNames = 0 ,
//int32_t *dnsIps = NULL ,
//int32_t numDnsIps = 0 ,
int32_t timeout = 60 ,
2013-08-03 00:12:24 +04:00
bool dnsLookup = false ,
// monitor.cpp passes in false for this:
bool cacheNotFounds = true );
2014-11-11 01:45:11 +03:00
bool sendToNextDNS ( struct DnsState *ds , int32_t timeout = 60 ) ;
2013-08-03 00:12:24 +04:00
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
2014-11-11 01:45:11 +03:00
int32_t gotIp ( UdpSlot *slot , struct DnsState *dnsState );
2013-08-03 00:12:24 +04:00
// . 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
2014-11-11 01:45:11 +03:00
bool isInCache (key_t key , int32_t *ip );
2013-08-03 00:12:24 +04:00
// add this hostnamekey/ip pair to the cache
2014-11-11 01:45:11 +03:00
void addToCache ( key_t hostnameKey , int32_t ip , int32_t ttl = -1 ) ;
2013-08-03 00:12:24 +04:00
// is it in the /etc/hosts file?
2014-11-11 01:45:11 +03:00
bool isInFile (key_t key , int32_t *ip );
2013-08-03 00:12:24 +04:00
2014-11-11 01:45:11 +03:00
key_t getKey ( char *hostname , int32_t hostnameLen ) ;
2013-08-03 00:12:24 +04:00
Host *getResponsibleHost ( key_t key ) ;
private:
bool loadFile ( );
2014-11-11 01:45:11 +03:00
//uint16_t m_dnsTransId;
2013-08-03 00:12:24 +04:00
// . 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;
2014-11-11 01:45:11 +03:00
int16_t m_dnsClientPort;
2013-08-03 00:12:24 +04:00
//char *m_dnsDir;
2014-11-11 01:45:11 +03:00
int32_t m_dnsIp;
int16_t m_dnsPort; // we talk to dns thru this port
2013-08-03 00:12:24 +04:00
2014-11-11 01:45:11 +03:00
int32_t m_numBind9Dns;
2013-08-03 00:12:24 +04:00
// /etc/hosts in hashed into this table
2014-11-11 01:45:11 +03:00
int32_t *m_ips;
2013-08-03 00:12:24 +04:00
key_t *m_keys;
2014-11-11 01:45:11 +03:00
int32_t m_numSlots;
2013-08-03 00:12:24 +04:00
};
//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