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>;