Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 #ifndef _PARENT_SELECTION_H_
00032 #define _PARENT_SELECTION_H_
00033 
00034 #include "Main.h"
00035 #include "ProxyConfig.h"
00036 #include "ControlBase.h"
00037 #include "ControlMatcher.h"
00038 
00039 #include "ink_apidefs.h"
00040 
00041 #include "P_RecProcess.h"
00042 
00043 #include "libts.h"
00044 
00045 #define MAX_PARENTS 64
00046 
00047 struct RequestData;
00048 
00049 struct matcher_line;
00050 struct ParentResult;
00051 class ParentRecord;
00052 
00053 enum ParentResultType
00054 {
00055   PARENT_UNDEFINED, PARENT_DIRECT,
00056   PARENT_SPECIFIED, PARENT_AGENT, PARENT_FAIL
00057 };
00058 
00059 typedef ControlMatcher<ParentRecord, ParentResult> P_table;
00060 
00061 
00062 
00063 
00064 struct ParentResult
00065 {
00066   ParentResult()
00067     : r(PARENT_UNDEFINED), hostname(NULL), port(0), line_number(0), epoch(NULL), rec(NULL),
00068       last_parent(0), start_parent(0), wrap_around(false), retry(false)
00069   { memset(foundParents, 0, sizeof(foundParents)); };
00070 
00071   
00072   ParentResultType r;
00073   const char *hostname;
00074   int port;
00075 
00076   
00077   
00078   int line_number;
00079   P_table *epoch;               
00080   ParentRecord *rec;
00081   uint32_t last_parent;
00082   uint32_t start_parent;
00083   bool wrap_around;
00084   bool retry;
00085   
00086   ATSConsistentHashIter chashIter;
00087   bool foundParents[MAX_PARENTS];
00088 };
00089 
00090 class HttpRequestData;
00091 
00092 struct ParentConfigParams:public ConfigInfo
00093 {
00094   ParentConfigParams();
00095   ~ParentConfigParams();
00096 
00097   
00098   
00099   
00100   
00101   inkcoreapi void findParent(HttpRequestData *rdata, ParentResult *result);
00102 
00103   
00104   
00105   
00106   
00107   inkcoreapi void markParentDown(ParentResult *result);
00108 
00109   
00110   
00111   
00112   
00113   
00114   void recordRetrySuccess(ParentResult *result);
00115 
00116   
00117   
00118   
00119   
00120   
00121   inkcoreapi void nextParent(HttpRequestData *rdata, ParentResult *result);
00122 
00123   
00124   
00125   
00126   
00127   bool parentExists(HttpRequestData *rdata);
00128 
00129   
00130   
00131   
00132   bool apiParentExists(HttpRequestData *rdata);
00133 
00134   P_table *ParentTable;
00135   ParentRecord *DefaultParent;
00136   int32_t ParentRetryTime;
00137   int32_t ParentEnable;
00138   int32_t FailThreshold;
00139   int32_t DNS_ParentOnly;
00140 };
00141 
00142 struct ParentConfig
00143 {
00144 public:
00145   static void startup();
00146   static void reconfigure();
00147   static void print();
00148 
00149   inkcoreapi static ParentConfigParams *acquire() { return (ParentConfigParams *) configProcessor.get(ParentConfig::m_id); }
00150   inkcoreapi static void release(ParentConfigParams *params) { configProcessor.release(ParentConfig::m_id, params); }
00151 
00152 
00153   static int m_id;
00154 };
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 struct pRecord : ATSConsistentHashNode
00165 {
00166   char hostname[MAXDNAME + 1];
00167   int port;
00168   time_t failedAt;
00169   int failCount;
00170   int32_t upAt;
00171   const char *scheme;           
00172   int idx;
00173   float weight;
00174 };
00175 
00176 enum ParentRR_t
00177 {
00178   P_NO_ROUND_ROBIN = 0,
00179   P_STRICT_ROUND_ROBIN,
00180   P_HASH_ROUND_ROBIN,
00181   P_CONSISTENT_HASH
00182 };
00183 
00184 
00185 
00186 
00187 
00188 
00189 class ParentRecord: public ControlBase
00190 {
00191 public:
00192   ParentRecord()
00193     : parents(NULL), num_parents(0), round_robin(P_NO_ROUND_ROBIN), rr_next(0), go_direct(true), chash(NULL)
00194   { }
00195 
00196   ~ParentRecord();
00197 
00198   char *Init(matcher_line *line_info);
00199   bool DefaultInit(char *val);
00200   void UpdateMatch(ParentResult *result, RequestData *rdata);
00201   void FindParent(bool firstCall, ParentResult *result, RequestData *rdata, ParentConfigParams *config);
00202   void Print();
00203   pRecord *parents;
00204   int num_parents;
00205 
00206   bool bypass_ok() const { return go_direct; }
00207 
00208   const char *scheme;
00209   
00210   const char *ProcessParents(char *val);
00211   void buildConsistentHash(void);
00212   ParentRR_t round_robin;
00213   volatile uint32_t rr_next;
00214   bool go_direct;
00215   ATSConsistentHash *chash;
00216 };
00217 
00218 
00219 ParentRecord *createDefaultParent(char *val);
00220 void reloadDefaultParent(char *val);
00221 void reloadParentFile();
00222 int parentSelection_CB(const char *name, RecDataT data_type, RecData data, void *cookie);
00223 
00224 
00225 void show_result(ParentResult *aParentResult);
00226 void br(HttpRequestData *h, const char *os_hostname, sockaddr const* dest_ip = NULL);       
00227 int verify(ParentResult *r, ParentResultType e, const char *h, int p);
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 struct SocksServerConfig
00240 {
00241   static void startup();
00242   static void reconfigure();
00243   static void print();
00244 
00245   static ParentConfigParams *acquire() { return (ParentConfigParams *) configProcessor.get(SocksServerConfig::m_id); }
00246   static void release(ParentConfigParams *params) { configProcessor.release(SocksServerConfig::m_id, params); }
00247 
00248   static int m_id;
00249 };
00250 
00251 #endif