00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #if !defined (_P_DNSProcessor_h_)
00025 #define _P_DNSProcessor_h_
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "I_EventSystem.h"
00035
00036 #define MAX_NAMED 32
00037 #define DEFAULT_DNS_RETRIES 5
00038 #define MAX_DNS_RETRIES 9
00039 #define DEFAULT_DNS_TIMEOUT 30
00040 #define MAX_DNS_IN_FLIGHT 2048
00041 #define DEFAULT_FAILOVER_NUMBER (DEFAULT_DNS_RETRIES + 1)
00042 #define DEFAULT_FAILOVER_PERIOD (DEFAULT_DNS_TIMEOUT + 30)
00043
00044
00045 #define DEFAULT_FAILOVER_TRY_PERIOD (DEFAULT_DNS_TIMEOUT + 1)
00046 #define DEFAULT_DNS_SEARCH 1
00047 #define FAILOVER_SOON_RETRY 5
00048 #define NO_NAMESERVER_SELECTED -1
00049
00050
00051
00052
00053 extern int dns_timeout;
00054 extern int dns_retries;
00055 extern int dns_search;
00056 extern int dns_failover_number;
00057 extern int dns_failover_period;
00058 extern int dns_failover_try_period;
00059 extern int dns_max_dns_in_flight;
00060 extern unsigned int dns_sequence_number;
00061
00062
00063
00064
00065
00066 #define DNS_PERIOD HRTIME_MSECONDS(-100)
00067 #define DNS_DELAY_PERIOD HRTIME_MSECONDS(10)
00068 #define DNS_SEQUENCE_NUMBER_RESTART_OFFSET 4000
00069 #define DNS_PRIMARY_RETRY_PERIOD HRTIME_SECONDS(5)
00070 #define DNS_PRIMARY_REOPEN_PERIOD HRTIME_SECONDS(60)
00071 #define BAD_DNS_RESULT ((HostEnt*)(uintptr_t)-1)
00072 #define DEFAULT_NUM_TRY_SERVER 8
00073
00074
00075 #ifndef HFIXEDSZ
00076 #define HFIXEDSZ 12
00077 #endif
00078 #ifndef QFIXEDSZ
00079 #define QFIXEDSZ 4
00080 #endif
00081
00082
00083
00084
00085 #define DNS_EVENT_LOOKUP DNS_EVENT_EVENTS_START
00086
00087 extern int dns_fd;
00088
00089 void *dns_udp_receiver(void *arg);
00090
00091
00092
00093 enum DNS_Stats
00094 {
00095 dns_total_lookups_stat,
00096 dns_response_time_stat,
00097 dns_success_time_stat,
00098 dns_lookup_success_stat,
00099 dns_lookup_fail_stat,
00100 dns_fail_time_stat,
00101 dns_retries_stat,
00102 dns_max_retries_exceeded_stat,
00103 dns_sequence_number_stat,
00104 dns_in_flight_stat,
00105 DNS_Stat_Count
00106 };
00107
00108 struct HostEnt;
00109 struct DNSHandler;
00110
00111 struct RecRawStatBlock;
00112 extern RecRawStatBlock *dns_rsb;
00113
00114
00115
00116 #define DNS_DEBUG_COUNT_DYN_STAT(_x, _y) \
00117 RecIncrRawStatCount(dns_rsb, mutex->thread_holding, (int)_x, _y)
00118
00119 #define DNS_INCREMENT_DYN_STAT(_x) \
00120 RecIncrRawStatSum(dns_rsb, mutex->thread_holding, (int)_x, 1)
00121
00122 #define DNS_DECREMENT_DYN_STAT(_x) \
00123 RecIncrRawStatSum(dns_rsb, mutex->thread_holding, (int)_x, -1)
00124
00125 #define DNS_SUM_DYN_STAT(_x, _r) \
00126 RecIncrRawStatSum(dns_rsb, mutex->thread_holding, (int)_x, _r)
00127
00128 #define DNS_READ_DYN_STAT(_x, _count, _sum) do { \
00129 RecGetRawStatSum(dns_rsb, (int)_x, &_sum); \
00130 RecGetRawStatCount(dns_rsb, (int)_x, &_count); \
00131 } while (0)
00132
00133 #define DNS_SET_DYN_COUNT(_x, _count) \
00134 RecSetRawStatCount(dns_rsb, _x, _count);
00135
00136 #define DNS_INCREMENT_THREAD_DYN_STAT(_s, _t) \
00137 RecIncrRawStatSum(dns_rsb, _t, (int) _s, 1);
00138
00139 #define DNS_DECREMENT_THREAD_DYN_STAT(_s, _t) \
00140 RecIncrRawStatSum(dns_rsb, _t, (int) _s, -1);
00141
00142
00143
00144
00145
00146
00147
00148 struct DNSEntry: public Continuation
00149 {
00150 int id[MAX_DNS_RETRIES];
00151 int qtype;
00152 HostResStyle host_res_style;
00153 int retries;
00154 int which_ns;
00155 ink_hrtime submit_time;
00156 ink_hrtime send_time;
00157 char qname[MAXDNAME];
00158 int qname_len;
00159 int orig_qname_len;
00160 char **domains;
00161 EThread *submit_thread;
00162 Action action;
00163 Event *timeout;
00164 Ptr<HostEnt> result_ent;
00165 DNSHandler *dnsH;
00166 bool written_flag;
00167 bool once_written_flag;
00168 bool last;
00169 LINK(DNSEntry, dup_link);
00170 Que(DNSEntry, dup_link) dups;
00171
00172 int mainEvent(int event, Event *e);
00173 int delayEvent(int event, Event *e);
00174 int post(DNSHandler *h, HostEnt *ent);
00175 int postEvent(int event, Event *e);
00176 void init(const char *x, int len, int qtype_arg, Continuation *acont, DNSProcessor::Options const& opt);
00177
00178 DNSEntry()
00179 : Continuation(NULL),
00180 qtype(0),
00181 host_res_style(HOST_RES_NONE),
00182 retries(DEFAULT_DNS_RETRIES),
00183 which_ns(NO_NAMESERVER_SELECTED), submit_time(0), send_time(0), qname_len(0),
00184 orig_qname_len(0), domains(0), timeout(0), result_ent(0), dnsH(0), written_flag(false),
00185 once_written_flag(false), last(false)
00186 {
00187 for (int i = 0; i < MAX_DNS_RETRIES; i++)
00188 id[i] = -1;
00189 memset(qname, 0, MAXDNAME);
00190 }
00191 };
00192
00193
00194 typedef int (DNSEntry::*DNSEntryHandler) (int, void *);
00195
00196 struct DNSEntry;
00197
00198
00199
00200
00201
00202
00203 struct DNSHandler: public Continuation
00204 {
00205
00206 IpEndpoint ip;
00207 IpEndpoint local_ipv6;
00208 IpEndpoint local_ipv4;
00209 int ifd[MAX_NAMED];
00210 int n_con;
00211 DNSConnection con[MAX_NAMED];
00212 int options;
00213 Queue<DNSEntry> entries;
00214 Queue<DNSConnection> triggered;
00215 int in_flight;
00216 int name_server;
00217 int in_write_dns;
00218 HostEnt *hostent_cache;
00219
00220 int ns_down[MAX_NAMED];
00221 int failover_number[MAX_NAMED];
00222 int failover_soon_number[MAX_NAMED];
00223 ink_hrtime crossed_failover_number[MAX_NAMED];
00224 ink_hrtime last_primary_retry;
00225 ink_hrtime last_primary_reopen;
00226
00227 ink_res_state m_res;
00228 int txn_lookup_timeout;
00229
00230 InkRand generator;
00231
00232 uint64_t qid_in_flight[(USHRT_MAX+1)/64];
00233
00234 void received_one(int i)
00235 {
00236 failover_number[i] = failover_soon_number[i] = crossed_failover_number[i] = 0;
00237 }
00238
00239 void sent_one()
00240 {
00241 ++failover_number[name_server];
00242 Debug("dns", "sent_one: failover_number for resolver %d is %d", name_server, failover_number[name_server]);
00243 if (failover_number[name_server] >= dns_failover_number && !crossed_failover_number[name_server])
00244 crossed_failover_number[name_server] = ink_get_hrtime();
00245 }
00246
00247 bool failover_now(int i)
00248 {
00249 if (is_debug_tag_set("dns")) {
00250 Debug("dns", "failover_now: Considering immediate failover, target time is %" PRId64 "",
00251 (ink_hrtime)HRTIME_SECONDS(dns_failover_period));
00252 Debug("dns", "\tdelta time is %" PRId64 "", (ink_get_hrtime() - crossed_failover_number[i]));
00253 }
00254 return (crossed_failover_number[i] &&
00255 ((ink_get_hrtime() - crossed_failover_number[i]) > HRTIME_SECONDS(dns_failover_period)));
00256 }
00257
00258 bool failover_soon(int i) {
00259 return (crossed_failover_number[i] &&
00260 ((ink_get_hrtime() - crossed_failover_number[i]) >
00261 (HRTIME_SECONDS(dns_failover_try_period + failover_soon_number[i] * FAILOVER_SOON_RETRY))));
00262 }
00263
00264 void recv_dns(int event, Event *e);
00265 int startEvent(int event, Event *e);
00266 int startEvent_sdns(int event, Event *e);
00267 int mainEvent(int event, Event *e);
00268
00269 void open_con(sockaddr const* addr, bool failed = false, int icon = 0);
00270 void failover();
00271 void rr_failure(int ndx);
00272 void recover();
00273 void retry_named(int ndx, ink_hrtime t, bool reopen = true);
00274 void try_primary_named(bool reopen = true);
00275 void switch_named(int ndx);
00276 uint16_t get_query_id();
00277
00278 void release_query_id(uint16_t qid) {
00279 qid_in_flight[qid >> 6] &= (uint64_t)~(0x1ULL << (qid & 0x3F));
00280 };
00281
00282 void set_query_id_in_use(uint16_t qid) {
00283 qid_in_flight[qid >> 6] |= (uint64_t)(0x1ULL << (qid & 0x3F));
00284 };
00285
00286 bool query_id_in_use(uint16_t qid) {
00287 return (qid_in_flight[(uint16_t)(qid) >> 6] & (uint64_t)(0x1ULL << ((uint16_t)(qid) & 0x3F))) != 0;
00288 };
00289
00290 DNSHandler();
00291
00292 private:
00293
00294 void validate_ip();
00295 };
00296
00297
00298
00299
00300
00301
00302 struct DNSServer
00303 {
00304 IpEndpoint x_server_ip[MAXNS];
00305 char x_dns_ip_line[MAXDNAME * 2];
00306
00307 char x_def_domain[MAXDNAME];
00308 char x_domain_srch_list[MAXDNAME];
00309
00310 DNSHandler *x_dnsH;
00311
00312 DNSServer()
00313 : x_dnsH(NULL)
00314 {
00315 memset(x_server_ip, 0, sizeof(x_server_ip));
00316
00317 memset(x_def_domain, 0, MAXDNAME);
00318 memset(x_domain_srch_list, 0, MAXDNAME);
00319 memset(x_dns_ip_line, 0, MAXDNAME * 2);
00320 }
00321 };
00322
00323
00324 TS_INLINE DNSHandler::DNSHandler()
00325 : Continuation(NULL), n_con(0), options(0), in_flight(0), name_server(0), in_write_dns(0),
00326 hostent_cache(0), last_primary_retry(0), last_primary_reopen(0),
00327 m_res(0), txn_lookup_timeout(0), generator((uint32_t)((uintptr_t)time(NULL) ^ (uintptr_t)this))
00328 {
00329 ats_ip_invalidate(&ip);
00330 for (int i = 0; i < MAX_NAMED; i++) {
00331 ifd[i] = -1;
00332 failover_number[i] = 0;
00333 failover_soon_number[i] = 0;
00334 crossed_failover_number[i] = 0;
00335 ns_down[i] = 1;
00336 con[i].handler = this;
00337 }
00338 memset(&qid_in_flight, 0, sizeof(qid_in_flight));
00339 SET_HANDLER(&DNSHandler::startEvent);
00340 Debug("net_epoll", "inline DNSHandler::DNSHandler()");
00341 }
00342
00343 #define DOT_SEPARATED(_x) \
00344 ((unsigned char*)&(_x))[0], ((unsigned char*)&(_x))[1], \
00345 ((unsigned char*)&(_x))[2], ((unsigned char*)&(_x))[3]
00346
00347 #endif