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 #include "ink_config.h"
00032 #include <sys/types.h>
00033 #include "Main.h"
00034 #include "ProxyConfig.h"
00035 #include "ControlMatcher.h"
00036 #include "CacheControl.h"
00037 #include "ParentSelection.h"
00038 #include "HostLookup.h"
00039 #include "HTTP.h"
00040 #include "URL.h"
00041 #include "P_EventSystem.h"
00042 #include "P_Net.h"
00043 #include "P_Cache.h"
00044 #include "P_SplitDNS.h"
00045 #include "congest/Congestion.h"
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 char *
00057 HttpRequestData::get_string()
00058 {
00059   char *str = hdr->url_string_get(NULL);
00060 
00061   if (str)
00062     unescapifyStr(str);
00063   return str;
00064 }
00065 
00066 const char *
00067 HttpRequestData::get_host()
00068 {
00069   return hostname_str;
00070 }
00071 
00072 sockaddr const*
00073 HttpRequestData::get_ip()
00074 {
00075   return &dest_ip.sa;
00076 }
00077 
00078 sockaddr const*
00079 HttpRequestData::get_client_ip()
00080 {
00081   return &src_ip.sa;
00082 }
00083 
00084 
00085 
00086 
00087 
00088 template<class Data, class Result> HostMatcher<Data, Result>::HostMatcher(const char *name, const char *filename)
00089   : data_array(NULL),
00090     array_len(-1),
00091     num_el(-1),
00092     matcher_name(name),
00093     file_name(filename)
00094 {
00095   host_lookup = new HostLookup(name);
00096 }
00097 
00098 template<class Data, class Result> HostMatcher<Data, Result>::~HostMatcher()
00099 {
00100   delete host_lookup;
00101   delete[]data_array;
00102 }
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 template<class Data, class Result> void HostMatcher<Data, Result>::Print()
00111 {
00112 
00113   printf("\tHost/Domain Matcher with %d elements\n", num_el);
00114   host_lookup->Print(PrintFunc);
00115 }
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 template<class Data, class Result> void HostMatcher<Data, Result>::PrintFunc(void *opaque_data)
00124 {
00125   Data *d = (Data *) opaque_data;
00126   d->Print();
00127 }
00128 
00129 
00130 
00131 
00132 
00133 template<class Data, class Result> void HostMatcher<Data, Result>::AllocateSpace(int num_entries)
00134 {
00135   
00136   ink_assert(array_len == -1);
00137 
00138   host_lookup->AllocateSpace(num_entries);
00139 
00140   data_array = new Data[num_entries];
00141 
00142   array_len = num_entries;
00143   num_el = 0;
00144 }
00145 
00146 
00147 
00148 
00149 
00150 
00151 template<class Data, class Result> void HostMatcher<Data, Result>::Match(RequestData * rdata, Result * result)
00152 {
00153   void *opaque_ptr;
00154   Data *data_ptr;
00155   bool r;
00156 
00157   
00158   
00159   if (num_el <= 0) {
00160     return;
00161   }
00162 
00163   HostLookupState s;
00164 
00165   r = host_lookup->MatchFirst(rdata->get_host(), &s, &opaque_ptr);
00166 
00167   while (r == true) {
00168     ink_assert(opaque_ptr != NULL);
00169     data_ptr = (Data *) opaque_ptr;
00170     data_ptr->UpdateMatch(result, rdata);
00171 
00172     r = host_lookup->MatchNext(&s, &opaque_ptr);
00173   }
00174 }
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 template<class Data, class Result> char *HostMatcher<Data, Result>::NewEntry(matcher_line * line_info)
00187 {
00188   Data *cur_d;
00189   char *errBuf;
00190   char *match_data;
00191 
00192   
00193   ink_assert(num_el >= 0);
00194   ink_assert(array_len >= 0);
00195 
00196   
00197   ink_assert(num_el < array_len);
00198 
00199   match_data = line_info->line[1][line_info->dest_entry];
00200 
00201   
00202   ink_assert(line_info->dest_entry < MATCHER_MAX_TOKENS);
00203   ink_assert(match_data != NULL);
00204 
00205   
00206   line_info->line[0][line_info->dest_entry] = 0;
00207   line_info->num_el--;
00208 
00209   
00210   cur_d = data_array + num_el;
00211   errBuf = cur_d->Init(line_info);
00212 
00213   if (errBuf != NULL) {
00214     
00215     memset(cur_d, 0, sizeof(Data));
00216     return errBuf;
00217   }
00218   
00219   host_lookup->NewEntry(match_data, (line_info->type == MATCH_DOMAIN) ? true : false, cur_d);
00220 
00221   num_el++;
00222   return NULL;
00223 }
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 
00232 template<class Data, class Result> UrlMatcher<Data, Result>::UrlMatcher(const char *name, const char *filename)
00233   : url_ht(NULL),
00234     num_el(-1),
00235     matcher_name(name),
00236     file_name(filename)
00237 {
00238   url_ht = ink_hash_table_create(InkHashTableKeyType_String);
00239 }
00240 
00241 
00242 
00243 
00244 template<class Data, class Result> UrlMatcher<Data, Result>::~UrlMatcher()
00245 {
00246   ink_hash_table_destroy(url_ht);
00247   for (int i = 0; i < num_el; i++) {
00248     ats_free(url_str[i]);
00249   }
00250   delete[]url_str;
00251   delete[]url_value;
00252   delete[]data_array;
00253 }
00254 
00255 
00256 
00257 
00258 
00259 
00260 template<class Data, class Result> void UrlMatcher<Data, Result>::Print()
00261 {
00262   printf("\tUrl Matcher with %d elements\n", num_el);
00263   for (int i = 0; i < num_el; i++) {
00264     printf("\t\tUrl: %s\n", url_str[i]);
00265     data_array[i].Print();
00266   }
00267 }
00268 
00269 
00270 
00271 
00272 template<class Data, class Result> void UrlMatcher<Data, Result>::AllocateSpace(int num_entries)
00273 {
00274   
00275   ink_assert(array_len == -1);
00276 
00277   data_array = new Data[num_entries];
00278   url_value = new int [num_entries];
00279   url_str = new char *[num_entries];
00280   memset(url_str, 0, sizeof(char *) * num_entries);
00281   array_len = num_entries;
00282   num_el = 0;
00283 }
00284 
00285 
00286 
00287 
00288 template<class Data, class Result> char *UrlMatcher<Data, Result>::NewEntry(matcher_line * line_info)
00289 {
00290   Data *cur_d;
00291   char *errBuf;
00292   char *pattern;
00293   int *value;
00294 
00295   
00296   ink_assert(num_el >= 0);
00297   ink_assert(array_len >= 0);
00298 
00299   
00300   ink_assert(num_el < array_len);
00301 
00302   pattern = line_info->line[1][line_info->dest_entry];
00303   
00304   ink_assert(line_info->dest_entry < MATCHER_MAX_TOKENS);
00305   ink_assert(pattern != NULL);
00306 
00307   if (ink_hash_table_lookup(url_ht, pattern, (void **)&value)) {
00308     errBuf = (char *)ats_malloc(1024 * sizeof(char));
00309     *errBuf = '\0';
00310     snprintf(errBuf, 1024, "%s url expression error(have exist) at line %d position",
00311                  matcher_name, line_info->line_num);
00312     return errBuf;
00313   }
00314   
00315   
00316   line_info->line[0][line_info->dest_entry] = 0;
00317   line_info->num_el--;
00318 
00319   
00320   cur_d = data_array + num_el;
00321   errBuf = cur_d->Init(line_info);
00322 
00323   if (errBuf == NULL) {
00324     url_str[num_el] = ats_strdup(pattern);
00325     url_value[num_el] = num_el;
00326     ink_hash_table_insert(url_ht, url_str[num_el], (void *)&url_value[num_el]);
00327     num_el++;
00328   }
00329   return errBuf;
00330 }
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 template<class Data, class Result> void UrlMatcher<Data, Result>::Match(RequestData * rdata, Result * result)
00339 {
00340   char *url_str;
00341   int *value;
00342   
00343   
00344   
00345   if (num_el <= 0) {
00346     return;
00347   }
00348 
00349   url_str = rdata->get_string();
00350 
00351   
00352   
00353   if (url_str == NULL) {
00354     url_str = ats_strdup("");
00355   }
00356 
00357   if (ink_hash_table_lookup(url_ht, url_str, (void **)&value)) { 
00358     Debug("matcher", "%s Matched %s with url at line %d", matcher_name, url_str, data_array[*value].line_num);
00359     data_array[*value].UpdateMatch(result, rdata);
00360   }
00361 
00362   ats_free(url_str);
00363 }
00364 
00365 
00366 
00367 
00368 template<class Data, class Result> RegexMatcher<Data, Result>::RegexMatcher(const char *name, const char *filename)
00369   : re_array(NULL),
00370     re_str(NULL),
00371     data_array(NULL),
00372     array_len(-1),
00373     num_el(-1),
00374     matcher_name(name),
00375     file_name(filename)
00376 {
00377 }
00378 
00379 
00380 
00381 
00382 template<class Data, class Result> RegexMatcher<Data, Result>::~RegexMatcher()
00383 {
00384   for (int i = 0; i < num_el; i++) {
00385     pcre_free(re_array[i]);
00386     ats_free(re_str[i]);
00387   }
00388   delete[]re_str;
00389   ats_free(re_array);
00390   delete[]data_array;
00391 }
00392 
00393 
00394 
00395 
00396 
00397 
00398 template<class Data, class Result> void RegexMatcher<Data, Result>::Print()
00399 {
00400   printf("\tRegex Matcher with %d elements\n", num_el);
00401   for (int i = 0; i < num_el; i++) {
00402     printf("\t\tRegex: %s\n", re_str[i]);
00403     data_array[i].Print();
00404   }
00405 }
00406 
00407 
00408 
00409 
00410 template<class Data, class Result> void RegexMatcher<Data, Result>::AllocateSpace(int num_entries)
00411 {
00412   
00413   ink_assert(array_len == -1);
00414 
00415   re_array = (pcre**)ats_malloc(sizeof(pcre*) * num_entries);
00416   memset(re_array, 0, sizeof(pcre*) * num_entries);
00417 
00418   data_array = new Data[num_entries];
00419 
00420   re_str = new char *[num_entries];
00421   memset(re_str, 0, sizeof(char *) * num_entries);
00422 
00423   array_len = num_entries;
00424   num_el = 0;
00425 }
00426 
00427 
00428 
00429 
00430 template<class Data, class Result> char *RegexMatcher<Data, Result>::NewEntry(matcher_line * line_info)
00431 {
00432   Data *cur_d;
00433   char *errBuf;
00434   char *pattern;
00435   const char *error;
00436   int erroffset;
00437 
00438   
00439   ink_assert(num_el >= 0);
00440   ink_assert(array_len >= 0);
00441 
00442   
00443   ink_assert(num_el < array_len);
00444 
00445   pattern = line_info->line[1][line_info->dest_entry];
00446   
00447   ink_assert(line_info->dest_entry < MATCHER_MAX_TOKENS);
00448   ink_assert(pattern != NULL);
00449 
00450   
00451   re_array[num_el] = pcre_compile(pattern, 0, &error, &erroffset, NULL);
00452   if (!re_array[num_el]) {
00453     errBuf = (char *)ats_malloc(1024 * sizeof(char));
00454     *errBuf = '\0';
00455     snprintf(errBuf, 1024, "%s regular expression error at line %d position %d : %s",
00456                  matcher_name, line_info->line_num, erroffset, error);
00457     re_array[num_el] = NULL;
00458     return errBuf;
00459   }
00460   re_str[num_el] = ats_strdup(pattern);
00461 
00462   
00463   line_info->line[0][line_info->dest_entry] = 0;
00464   line_info->num_el--;
00465 
00466   
00467   cur_d = data_array + num_el;
00468   errBuf = cur_d->Init(line_info);
00469 
00470   if (errBuf == NULL) {
00471     num_el++;
00472   } else {
00473     
00474     ats_free(re_str[num_el]);
00475     re_str[num_el] = NULL;
00476     pcre_free(re_array[num_el]);
00477     re_array[num_el] = NULL;
00478   }
00479 
00480   return errBuf;
00481 }
00482 
00483 
00484 
00485 
00486 
00487 
00488 
00489 template<class Data, class Result> void RegexMatcher<Data, Result>::Match(RequestData * rdata, Result * result)
00490 {
00491   char *url_str;
00492   int r;
00493 
00494   
00495   
00496   if (num_el <= 0) {
00497     return;
00498   }
00499 
00500   url_str = rdata->get_string();
00501 
00502   
00503   
00504   if (url_str == NULL) {
00505     url_str = ats_strdup("");
00506   }
00507   
00508   
00509   
00510   
00511 
00512   for (int i = 0; i < num_el; i++) {
00513 
00514     r = pcre_exec(re_array[i], NULL, url_str, strlen(url_str), 0, 0, NULL, 0);
00515     if (r > -1) {
00516       Debug("matcher", "%s Matched %s with regex at line %d", matcher_name, url_str, data_array[i].line_num);
00517       data_array[i].UpdateMatch(result, rdata);
00518     } else if (r < -1) {
00519       
00520       Warning("Error [%d] matching regex at line %d.", r, data_array[i].line_num);
00521     } 
00522 
00523   }
00524   ats_free(url_str);
00525 }
00526 
00527 
00528 
00529 
00530 template<class Data, class Result>
00531 HostRegexMatcher<Data, Result>::HostRegexMatcher(const char *name, const char *filename)
00532     : RegexMatcher <Data, Result>(name, filename)
00533 {
00534 }
00535 
00536 
00537 
00538 
00539 
00540 
00541 
00542 template<class Data, class Result> void HostRegexMatcher<Data, Result>::Match(RequestData * rdata, Result * result)
00543 {
00544   const char *url_str;
00545   int r;
00546 
00547   
00548   
00549   if (this->num_el <= 0) {
00550     return;
00551   }
00552 
00553   url_str = rdata->get_host();
00554 
00555   
00556   
00557   if (url_str == NULL) {
00558     url_str = "";
00559   }
00560   for (int i = 0; i < this->num_el; i++) {
00561     r = pcre_exec(this->re_array[i], NULL, url_str, strlen(url_str), 0, 0, NULL, 0);
00562     if (r != -1) {
00563       Debug("matcher", "%s Matched %s with regex at line %d",
00564             const_cast<char*>(this->matcher_name), url_str, this->data_array[i].line_num);
00565       this->data_array[i].UpdateMatch(result, rdata);
00566     } else {
00567       
00568       Warning("error matching regex at line %d", this->data_array[i].line_num);
00569     }
00570   }
00571 }
00572 
00573 
00574 
00575 
00576 template<class Data, class Result> IpMatcher<Data, Result>::IpMatcher(const char *name, const char *filename)
00577   : data_array(NULL),
00578     array_len(-1),
00579     num_el(-1),
00580     matcher_name(name),
00581     file_name(filename)
00582 {
00583 }
00584 
00585 
00586 
00587 
00588 template<class Data, class Result> IpMatcher<Data, Result>::~IpMatcher()
00589 {
00590   delete[]data_array;
00591 }
00592 
00593 
00594 
00595 
00596 template<class Data, class Result> void IpMatcher<Data, Result>::AllocateSpace(int num_entries)
00597 {
00598   
00599   ink_assert(array_len == -1);
00600 
00601   data_array = new Data[num_entries];
00602 
00603   array_len = num_entries;
00604   num_el = 0;
00605 }
00606 
00607 
00608 
00609 
00610 
00611 
00612 
00613 
00614 
00615 
00616 
00617 template<class Data, class Result> char *IpMatcher<Data, Result>::NewEntry(matcher_line * line_info)
00618 {
00619 
00620   Data *cur_d;
00621   const char *errPtr;
00622   char *errBuf;
00623   char *match_data;
00624   IpEndpoint addr1, addr2;
00625 
00626   
00627   ink_assert(num_el >= 0);
00628   ink_assert(array_len >= 0);
00629 
00630   
00631   ink_assert(num_el < array_len);
00632 
00633   match_data = line_info->line[1][line_info->dest_entry];
00634 
00635   
00636   ink_assert(line_info->dest_entry < MATCHER_MAX_TOKENS);
00637   ink_assert(match_data != NULL);
00638 
00639   
00640   errPtr = ExtractIpRange(match_data, &addr1.sa, &addr2.sa);
00641   if (errPtr != NULL) {
00642     const size_t errorSize = 1024;
00643     errBuf = (char *)ats_malloc(errorSize * sizeof(char));
00644     snprintf(errBuf, errorSize, "%s %s at %s line %d", matcher_name, errPtr, file_name, line_info->line_num);
00645     return errBuf;
00646   }
00647 
00648   
00649   line_info->line[0][line_info->dest_entry] = NULL;
00650   line_info->num_el--;
00651 
00652   
00653   cur_d = data_array + num_el;
00654   errBuf = cur_d->Init(line_info);
00655   if (errBuf != NULL) {
00656     return errBuf;
00657   }
00658 
00659   ip_map.mark(&addr1.sa, &addr2.sa, cur_d);
00660 
00661   ++num_el;
00662   return NULL;
00663 }
00664 
00665 
00666 
00667 
00668 template<class Data, class Result>
00669 void IpMatcher<Data, Result>::Match(sockaddr const* addr, RequestData * rdata, Result * result)
00670 {
00671   void* raw;
00672   if (ip_map.contains(addr, &raw)) {
00673     Data *cur = static_cast<Data*>(raw);
00674     ink_assert(cur != 0);
00675     cur->UpdateMatch(result, rdata);
00676   }
00677 }
00678 
00679 
00680 template<class Data, class Result> void IpMatcher<Data, Result>::Print()
00681 {
00682   printf("\tIp Matcher with %d elements, %zu ranges.\n", num_el, ip_map.getCount());
00683   for ( IpMap::iterator spot(ip_map.begin()), limit(ip_map.end()) ; spot != limit ; ++spot) {
00684     char b1[INET6_ADDRSTRLEN], b2[INET6_ADDRSTRLEN];
00685     printf("\tRange %s - %s ",
00686       ats_ip_ntop(spot->min(), b1, sizeof b1),
00687       ats_ip_ntop(spot->max(), b2, sizeof b2)
00688     );
00689     static_cast<Data*>(spot->data())->Print();
00690   }
00691 }
00692 
00693 template<class Data, class Result>
00694 ControlMatcher<Data, Result>::ControlMatcher(const char *file_var, const char *name, const matcher_tags * tags,
00695                                              int flags_in)
00696 {
00697   flags = flags_in;
00698   ink_assert(flags & (ALLOW_HOST_TABLE | ALLOW_REGEX_TABLE | ALLOW_URL_TABLE | ALLOW_IP_TABLE));
00699 
00700   config_tags = tags;
00701   ink_assert(config_tags != NULL);
00702 
00703   matcher_name = name;
00704   config_file_path[0] = '\0';
00705 
00706   if (!(flags & DONT_BUILD_TABLE)) {
00707     ats_scoped_str config_path(RecConfigReadConfigPath(file_var));
00708 
00709     ink_release_assert(config_path);
00710     ink_strlcpy(config_file_path, config_path, sizeof(config_file_path));
00711   }
00712 
00713   reMatch = NULL;
00714   urlMatch = NULL;
00715   hostMatch = NULL;
00716   ipMatch = NULL;
00717   hrMatch = NULL;
00718 
00719   if (!(flags & DONT_BUILD_TABLE)) {
00720     m_numEntries = this->BuildTable();
00721   } else {
00722     m_numEntries = 0;
00723   }
00724 }
00725 
00726 template<class Data, class Result> ControlMatcher<Data, Result>::~ControlMatcher()
00727 {
00728 
00729   delete reMatch;
00730   delete urlMatch;
00731   delete hostMatch;
00732   delete ipMatch;
00733   delete hrMatch;
00734 }
00735 
00736 
00737 
00738 
00739 
00740 template<class Data, class Result> void ControlMatcher<Data, Result>::Print()
00741 {
00742   printf("Control Matcher Table: %s\n", matcher_name);
00743   if (hostMatch != NULL) {
00744     hostMatch->Print();
00745   }
00746   if (reMatch != NULL) {
00747     reMatch->Print();
00748   }
00749   if (urlMatch != NULL) {
00750     urlMatch->Print();
00751   }
00752   if (ipMatch != NULL) {
00753     ipMatch->Print();
00754   }
00755   if (hrMatch != NULL) {
00756     hrMatch->Print();
00757   }
00758 }
00759 
00760 
00761 
00762 
00763 
00764 
00765 
00766 template<class Data, class Result> void ControlMatcher<Data, Result>::Match(RequestData * rdata, Result * result)
00767 {
00768   if (hostMatch != NULL) {
00769     hostMatch->Match(rdata, result);
00770   }
00771   if (reMatch != NULL) {
00772     reMatch->Match(rdata, result);
00773   }
00774   if (urlMatch != NULL) {
00775     urlMatch->Match(rdata, result);
00776   }
00777   if (ipMatch != NULL) {
00778     ipMatch->Match(rdata->get_ip(), rdata, result);
00779   }
00780   if (hrMatch != NULL) {
00781     hrMatch->Match(rdata, result);
00782   }
00783 }
00784 
00785 int fstat_wrapper(int fd, struct stat *s);
00786 
00787 
00788 
00789 
00790 
00791 
00792 template<class Data, class Result> int ControlMatcher<Data, Result>::BuildTableFromString(char *file_buf)
00793 {
00794   
00795   Tokenizer bufTok("\n");
00796   tok_iter_state i_state;
00797   const char *tmp;
00798   matcher_line *first = NULL;
00799   matcher_line *current;
00800   matcher_line *last = NULL;
00801   int line_num = 0;
00802   int second_pass = 0;
00803   int numEntries = 0;
00804   bool alarmAlready = false;
00805   char errBuf[1024];
00806   const char *errPtr = NULL;
00807 
00808   
00809   int hostDomain = 0;
00810   int regex = 0;
00811   int url = 0;
00812   int ip = 0;
00813   int hostregex = 0;
00814 
00815   if (bufTok.Initialize(file_buf, SHARE_TOKS | ALLOW_EMPTY_TOKS) == 0) {
00816     
00817     return 0;
00818   }
00819   
00820   tmp = bufTok.iterFirst(&i_state);
00821   while (tmp != NULL) {
00822 
00823     line_num++;
00824 
00825     
00826     while (*tmp && isspace(*tmp)) {
00827       tmp++;
00828     }
00829 
00830     if (*tmp != '#' && *tmp != '\0') {
00831 
00832       current = (matcher_line *)ats_malloc(sizeof(matcher_line));
00833       errPtr = parseConfigLine((char *) tmp, current, config_tags);
00834 
00835       if (errPtr != NULL) {
00836         if (config_tags != &socks_server_tags) {
00837           snprintf(errBuf, sizeof(errBuf), "%s discarding %s entry at line %d : %s",
00838                    matcher_name, config_file_path, line_num, errPtr);
00839           SignalError(errBuf, alarmAlready);
00840         }
00841         ats_free(current);
00842       } else {
00843 
00844         
00845         
00846         numEntries++;
00847         current->line_num = line_num;
00848 
00849         switch (current->type) {
00850         case MATCH_HOST:
00851         case MATCH_DOMAIN:
00852           hostDomain++;
00853           break;
00854         case MATCH_IP:
00855           ip++;
00856           break;
00857         case MATCH_REGEX:
00858           regex++;
00859           break;
00860         case MATCH_URL:
00861           url++;
00862           break;
00863         case MATCH_HOST_REGEX:
00864           hostregex++;
00865           break;
00866         case MATCH_NONE:
00867         default:
00868           ink_assert(0);
00869         }
00870 
00871         if (first == NULL) {
00872           ink_assert(last == NULL);
00873           first = last = current;
00874         } else {
00875           last->next = current;
00876           last = current;
00877         }
00878       }
00879     }
00880     tmp = bufTok.iterNext(&i_state);
00881   }
00882 
00883   
00884   if (numEntries == 0) {
00885     ats_free(first);
00886     return 0;
00887   }
00888   
00889   if ((flags & ALLOW_REGEX_TABLE) && regex > 0) {
00890     reMatch = new RegexMatcher<Data, Result> (matcher_name, config_file_path);
00891     reMatch->AllocateSpace(regex);
00892   }
00893 
00894   if ((flags & ALLOW_URL_TABLE) && url > 0) {
00895     urlMatch = new UrlMatcher<Data, Result> (matcher_name, config_file_path);
00896     urlMatch->AllocateSpace(url);
00897   }
00898 
00899   if ((flags & ALLOW_HOST_TABLE) && hostDomain > 0) {
00900     hostMatch = new HostMatcher<Data, Result> (matcher_name, config_file_path);
00901     hostMatch->AllocateSpace(hostDomain);
00902   }
00903 
00904   if ((flags & ALLOW_IP_TABLE) && ip > 0) {
00905     ipMatch = new IpMatcher<Data, Result> (matcher_name, config_file_path);
00906     ipMatch->AllocateSpace(ip);
00907   }
00908 
00909   if ((flags & ALLOW_HOST_REGEX_TABLE) && hostregex > 0) {
00910     hrMatch = new HostRegexMatcher<Data, Result> (matcher_name, config_file_path);
00911     hrMatch->AllocateSpace(hostregex);
00912   }
00913   
00914   current = first;
00915   while (current != NULL) {
00916     second_pass++;
00917     if ((flags & ALLOW_HOST_TABLE) && current->type == MATCH_DOMAIN) {
00918       errPtr = hostMatch->NewEntry(current);
00919     } else if ((flags & ALLOW_HOST_TABLE) && current->type == MATCH_HOST) {
00920       errPtr = hostMatch->NewEntry(current);
00921     } else if ((flags & ALLOW_REGEX_TABLE) && current->type == MATCH_REGEX) {
00922       errPtr = reMatch->NewEntry(current);
00923     } else if ((flags & ALLOW_URL_TABLE) && current->type == MATCH_URL) {
00924       errPtr = urlMatch->NewEntry(current);
00925     } else if ((flags & ALLOW_IP_TABLE) && current->type == MATCH_IP) {
00926       errPtr = ipMatch->NewEntry(current);
00927     } else if ((flags & ALLOW_HOST_REGEX_TABLE) && current->type == MATCH_HOST_REGEX) {
00928       errPtr = hrMatch->NewEntry(current);
00929     } else {
00930       errPtr = NULL;
00931       snprintf(errBuf, sizeof(errBuf), "%s discarding %s entry with unknown type at line %d",
00932                matcher_name, config_file_path, current->line_num);
00933       SignalError(errBuf, alarmAlready);
00934     }
00935 
00936     
00937     
00938     if (errPtr != NULL) {
00939       SignalError(errPtr, alarmAlready);
00940       
00941       errPtr = NULL;
00942     }
00943     
00944     last = current;
00945     current = current->next;
00946     ats_free(last);
00947   }
00948 
00949   ink_assert(second_pass == numEntries);
00950 
00951   if (is_debug_tag_set("matcher")) {
00952     Print();
00953   }
00954   return numEntries;
00955 }
00956 
00957 template<class Data, class Result> int ControlMatcher<Data, Result>::BuildTable()
00958 {
00959   
00960   char *file_buf;
00961   int ret;
00962 
00963   file_buf = readIntoBuffer(config_file_path, matcher_name, NULL);
00964 
00965   if (file_buf == NULL) {
00966     return 1;
00967   }
00968 
00969   ret = BuildTableFromString(file_buf);
00970   ats_free(file_buf);
00971   return ret;
00972 }
00973 
00974 
00975 
00976 
00977 
00978 
00979 
00980 
00981 
00982 
00983 
00984 
00985 
00986 
00987 
00988 
00989 
00990 
00991 
00992 
00993 
00994 
00995 
00996 
00997 
00998 
00999 
01000 
01001 
01002 
01003 
01004 template class ControlMatcher<ParentRecord, ParentResult>;
01005 template class HostMatcher<ParentRecord, ParentResult>;
01006 template class RegexMatcher<ParentRecord, ParentResult>;
01007 template class UrlMatcher<ParentRecord, ParentResult>;
01008 template class IpMatcher<ParentRecord, ParentResult>;
01009 template class HostRegexMatcher<ParentRecord, ParentResult>;
01010 
01011 template class ControlMatcher<SplitDNSRecord, SplitDNSResult>;
01012 template class HostMatcher<SplitDNSRecord, SplitDNSResult>;
01013 template class RegexMatcher<SplitDNSRecord, SplitDNSResult>;
01014 template class UrlMatcher<SplitDNSRecord, SplitDNSResult>;
01015 template class IpMatcher<SplitDNSRecord, SplitDNSResult>;
01016 template class HostRegexMatcher<SplitDNSRecord, SplitDNSResult>;
01017 
01018 template class ControlMatcher<CacheControlRecord, CacheControlResult>;
01019 template class HostMatcher<CacheControlRecord, CacheControlResult>;
01020 template class RegexMatcher<CacheControlRecord, CacheControlResult>;
01021 template class UrlMatcher<CacheControlRecord, CacheControlResult>;
01022 template class IpMatcher<CacheControlRecord, CacheControlResult>;
01023 
01024 template class ControlMatcher<CongestionControlRecord, CongestionControlRule>;
01025 template class HostMatcher<CongestionControlRecord, CongestionControlRule>;
01026 template class HostRegexMatcher<CongestionControlRecord, CongestionControlRule>;
01027 template class RegexMatcher<CongestionControlRecord, CongestionControlRule>;
01028 template class UrlMatcher<CongestionControlRecord, CongestionControlRule>;
01029 template class IpMatcher<CongestionControlRecord, CongestionControlRule>;