• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

P_DNSProcessor.h

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 #if !defined (_P_DNSProcessor_h_)
00025 #define _P_DNSProcessor_h_
00026 
00027 /*
00028   #include "I_DNS.h"
00029   #include "libts.h"
00030   #include <arpa/nameser.h>
00031   #include "I_Cache.h"
00032   #include "P_Net.h"
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 // how many seconds before FAILOVER_PERIOD to try the primary with
00044 // a well known address
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 // Config
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 // Constants
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 // these are from nameser.h
00075 #ifndef HFIXEDSZ
00076 #define HFIXEDSZ 12
00077 #endif
00078 #ifndef QFIXEDSZ
00079 #define QFIXEDSZ 4
00080 #endif
00081 
00082 
00083 // Events
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 //Stats
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 // Stat Macros
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   One DNSEntry is allocated per outstanding request. This continuation
00144   handles TIMEOUT events for the request as well as storing all
00145   information about the request and its status.
00146 
00147 */
00148 struct DNSEntry: public Continuation
00149 {
00150   int id[MAX_DNS_RETRIES];
00151   int qtype; ///< Type of query to send.
00152   HostResStyle host_res_style; ///< Preferred IP address family.
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   One DNSHandler is allocated to handle all DNS traffic by polling a
00200   UDP port.
00201 
00202 */
00203 struct DNSHandler: public Continuation
00204 {
00205   /// This is used as the target if round robin isn't set.
00206   IpEndpoint ip;
00207   IpEndpoint local_ipv6; ///< Local V6 address if set.
00208   IpEndpoint local_ipv4; ///< Local V4 address if set.
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   // bitmap of query ids in use
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   // Check the IP address and switch to default if needed.
00294   void validate_ip();
00295 };
00296 
00297 /* --------------------------------------------------------------
00298    **                struct DNSServer
00299 
00300    A record for an single server
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

Generated by  doxygen 1.7.1