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 #include "libts.h"
00031 #include "HostLookup.h"
00032 #include "MatcherUtils.h"
00033
00034
00035
00036
00037
00038 bool
00039 domaincmp(const char *hostname, const char *domain)
00040 {
00041 ink_assert(hostname != NULL);
00042 ink_assert(domain != NULL);
00043
00044 const char *host_cur = hostname + strlen(hostname);
00045 const char *domain_cur = domain + strlen(domain);
00046
00047
00048
00049
00050 if (domain_cur == domain || host_cur == hostname) {
00051 return false;
00052 }
00053
00054 domain_cur--;
00055 host_cur--;
00056
00057
00058
00059 if (*(domain_cur) == '.') {
00060 domain_cur--;
00061 }
00062 if (*(host_cur) == '.') {
00063 host_cur--;
00064 }
00065
00066 while (domain_cur >= domain && host_cur >= hostname) {
00067
00068
00069
00070
00071 if (tolower(*domain_cur) != tolower(*host_cur)) {
00072 return false;
00073 }
00074
00075 domain_cur--;
00076 host_cur--;
00077 };
00078
00079
00080
00081
00082
00083
00084
00085
00086 if (domain_cur < domain) {
00087 if (host_cur < hostname) {
00088
00089
00090 return true;
00091 } else {
00092
00093
00094
00095
00096
00097 if (*(domain_cur + 1) == '.') {
00098 return true;
00099 } else if (*host_cur == '.') {
00100 return true;
00101 } else {
00102 return false;
00103 }
00104 }
00105 } else if (host_cur < hostname) {
00106
00107
00108 if (*domain_cur == '.' && domain_cur == domain) {
00109 return true;
00110 } else {
00111 return false;
00112 }
00113 }
00114
00115 ink_assert(!"Should not get here");
00116 return false;
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 int
00131 hostcmp(const char *c1, const char *c2)
00132 {
00133 ink_assert(c1 != NULL);
00134 ink_assert(c2 != NULL);
00135 do {
00136 if (tolower(*c1) < tolower(*c2)) {
00137 if (*c1 == '\0' && *c2 == '.' && *(c2 + 1) == '\0') {
00138 break;
00139 }
00140 return -1;
00141 } else if (tolower(*c1) > tolower(*c2)) {
00142 if (*c2 == '\0' && *c1 == '.' && *(c1 + 1) == '\0') {
00143 break;
00144 }
00145 return 1;
00146 }
00147
00148 if (*c1 == '\0') {
00149 break;
00150 }
00151 c1++;
00152 c2++;
00153 } while (1);
00154
00155 return 0;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 static const unsigned char asciiToTable[256] = {
00173 255, 255, 255, 255, 255, 255, 255, 255,
00174 255, 255, 255, 255, 255, 255, 255, 255,
00175 255, 255, 255, 255, 255, 255, 255, 255,
00176 255, 255, 255, 255, 255, 255, 255, 255,
00177 255, 255, 255, 255, 255, 255, 255, 255,
00178 255, 255, 255, 255, 255, 0, 255, 255,
00179 1, 2, 3, 4, 5, 6, 7, 8,
00180 9, 10, 255, 255, 255, 255, 255, 255,
00181 255, 11, 12, 13, 14, 15, 16, 17,
00182 18, 19, 20, 21, 22, 23, 24, 25,
00183 26, 27, 28, 29, 30, 31, 32, 33,
00184 34, 35, 36, 255, 255, 255, 255, 37,
00185 255, 11, 12, 13, 14, 15, 16, 17,
00186 18, 19, 20, 21, 22, 23, 24, 25,
00187 26, 27, 28, 29, 30, 31, 32, 33,
00188 34, 35, 36, 255, 255, 255, 255, 255,
00189 255, 255, 255, 255, 255, 255, 255, 255,
00190 255, 255, 255, 255, 255, 255, 255, 255,
00191 255, 255, 255, 255, 255, 255, 255, 255,
00192 255, 255, 255, 255, 255, 255, 255, 255,
00193 255, 255, 255, 255, 255, 255, 255, 255,
00194 255, 255, 255, 255, 255, 255, 255, 255,
00195 255, 255, 255, 255, 255, 255, 255, 255,
00196 255, 255, 255, 255, 255, 255, 255, 255,
00197 255, 255, 255, 255, 255, 255, 255, 255,
00198 255, 255, 255, 255, 255, 255, 255, 255,
00199 255, 255, 255, 255, 255, 255, 255, 255,
00200 255, 255, 255, 255, 255, 255, 255, 255,
00201 255, 255, 255, 255, 255, 255, 255, 255,
00202 255, 255, 255, 255, 255, 255, 255, 255,
00203 255, 255, 255, 255, 255, 255, 255, 255,
00204 255, 255, 255, 255, 255, 255, 255, 255
00205 };
00206
00207
00208 static const int numLegalChars = 38;
00209
00210
00211
00212
00213
00214
00215 struct charIndex_el
00216 {
00217 charIndex_el();
00218 ~charIndex_el();
00219 HostBranch *branch_array[numLegalChars];
00220 charIndex_el *next_level[numLegalChars];
00221 };
00222
00223 charIndex_el::charIndex_el()
00224 {
00225 memset(branch_array, 0, sizeof(branch_array));
00226 memset(next_level, 0, sizeof(next_level));
00227 }
00228
00229 charIndex_el::~charIndex_el()
00230 {
00231 int i;
00232
00233
00234
00235 for (i = 0; i < numLegalChars; i++) {
00236 if (next_level[i] != NULL) {
00237 delete next_level[i];
00238 }
00239 }
00240 }
00241
00242
00243
00244
00245
00246
00247
00248 struct charIndexIterInternal
00249 {
00250 charIndex_el *ptr;
00251 int index;
00252 };
00253
00254
00255
00256 static charIndexIterInternal default_iter = { NULL, -1 };
00257
00258
00259
00260
00261
00262
00263 struct charIndexIterState
00264 {
00265 charIndexIterState();
00266
00267
00268 int cur_level;
00269
00270
00271 int cur_index;
00272 charIndex_el *cur_el;
00273
00274
00275 DynArray<charIndexIterInternal> q;
00276 };
00277
00278 charIndexIterState::charIndexIterState():cur_level(-1), cur_index(-1), cur_el(NULL), q(&default_iter, 6)
00279 {
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 class
00320 charIndex
00321 {
00322 public:
00323 charIndex();
00324 ~
00325 charIndex();
00326 void
00327 Insert(const char *match_data, HostBranch * toInsert);
00328 HostBranch *
00329 Lookup(const char *match_data);
00330 HostBranch *
00331 iter_first(charIndexIterState * s);
00332 HostBranch *
00333 iter_next(charIndexIterState * s);
00334 private:
00335 charIndex_el *
00336 root;
00337 InkHashTable *
00338 illegalKey;
00339 };
00340
00341 charIndex::charIndex():illegalKey(NULL)
00342 {
00343 root = new charIndex_el;
00344 }
00345
00346 charIndex::~charIndex()
00347 {
00348 InkHashTableIteratorState ht_iter;
00349 InkHashTableEntry *ht_entry = NULL;
00350 HostBranch *tmp;
00351
00352 delete root;
00353
00354
00355
00356 if (illegalKey != NULL) {
00357 ht_entry = ink_hash_table_iterator_first(illegalKey, &ht_iter);
00358
00359 while (ht_entry != NULL) {
00360 tmp = (HostBranch *) ink_hash_table_entry_value(illegalKey, ht_entry);
00361 ink_assert(tmp != NULL);
00362 delete tmp;
00363 ht_entry = ink_hash_table_iterator_next(illegalKey, &ht_iter);
00364 }
00365 ink_hash_table_destroy(illegalKey);
00366 }
00367 }
00368
00369
00370
00371
00372
00373 void
00374 charIndex::Insert(const char *match_data, HostBranch * toInsert)
00375 {
00376 unsigned char index;
00377 const char *match_start = match_data;
00378 charIndex_el *cur = root;
00379 charIndex_el *next;
00380
00381 if (*match_data == '\0') {
00382
00383 ink_assert(0);
00384 return;
00385 }
00386
00387 while (1) {
00388 index = asciiToTable[(unsigned char) (*match_data)];
00389
00390
00391
00392 if (index == 255) {
00393
00394 if (illegalKey == NULL) {
00395 illegalKey = ink_hash_table_create(InkHashTableKeyType_String);
00396 }
00397 ink_hash_table_insert(illegalKey, (char *) match_start, toInsert);
00398 break;
00399 }
00400
00401
00402 if (*(match_data + 1) == '\0') {
00403
00404
00405 ink_assert(cur->branch_array[index] == NULL);
00406 cur->branch_array[index] = toInsert;
00407 break;
00408 } else {
00409
00410
00411 next = cur->next_level[index];
00412
00413
00414 if (next == NULL) {
00415 next = new charIndex_el;
00416 cur->next_level[index] = next;
00417 }
00418 cur = next;
00419 }
00420 match_data++;
00421 }
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431 HostBranch *
00432 charIndex::Lookup(const char *match_data)
00433 {
00434 unsigned char index;
00435 charIndex_el *cur = root;
00436 void *hash_lookup;
00437 const char *match_start = match_data;
00438
00439 if (root == NULL || *match_data == '\0') {
00440 return NULL;
00441 }
00442
00443 while (1) {
00444
00445 index = asciiToTable[(unsigned char) (*match_data)];
00446
00447
00448
00449 if (index == 255) {
00450 if (illegalKey == NULL) {
00451 return NULL;
00452 } else {
00453 if (ink_hash_table_lookup(illegalKey, (char *) match_start, &hash_lookup)) {
00454 return (HostBranch *) hash_lookup;
00455 } else {
00456 return NULL;
00457 }
00458 }
00459 }
00460
00461
00462 if (*(match_data + 1) == '\0') {
00463 return cur->branch_array[index];
00464 } else {
00465 cur = cur->next_level[index];
00466
00467 if (cur == NULL) {
00468 return NULL;
00469 }
00470 }
00471
00472 match_data++;
00473 }
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483 HostBranch *
00484 charIndex::iter_first(charIndexIterState * s)
00485 {
00486 s->cur_level = 0;
00487 s->cur_index = -1;
00488 s->cur_el = root;
00489
00490 return iter_next(s);
00491 }
00492
00493
00494
00495
00496
00497
00498
00499
00500 HostBranch *
00501 charIndex::iter_next(charIndexIterState * s)
00502 {
00503 int index;
00504 charIndex_el *current_el = s->cur_el;
00505 intptr_t level = s->cur_level;
00506 charIndexIterInternal stored_state;
00507 HostBranch *r = NULL;
00508 bool first_element;
00509
00510
00511
00512
00513 if (s->cur_index < 0) {
00514 first_element = false;
00515 index = s->cur_index + 1;
00516 } else {
00517 first_element = true;
00518 index = s->cur_index;
00519 }
00520
00521 while (1) {
00522
00523
00524 if (index >= numLegalChars) {
00525 if (level <= 0) {
00526
00527 break;
00528 } else {
00529
00530 stored_state = s->q[level - 1];
00531 ink_assert(stored_state.ptr != NULL);
00532 ink_assert(stored_state.index >= 0);
00533 level--;
00534 current_el = stored_state.ptr;
00535 index = stored_state.index + 1;
00536 }
00537 } else {
00538
00539
00540
00541
00542
00543
00544 if (current_el->branch_array[index] != NULL && first_element == false) {
00545 r = current_el->branch_array[index];
00546 s->cur_level = level;
00547 s->cur_index = index;
00548 s->cur_el = current_el;
00549 break;
00550 } else if (current_el->next_level[index] != NULL) {
00551
00552
00553 stored_state.ptr = current_el;
00554 stored_state.index = index;
00555 s->q(level) = stored_state;
00556 current_el = current_el->next_level[index];
00557 index = 0;
00558 level++;
00559 } else {
00560
00561 index++;
00562 }
00563 }
00564 first_element = false;
00565 }
00566
00567 return r;
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 typedef int hostArrayIterState;
00579
00580 class hostArray
00581 {
00582 public:
00583 hostArray();
00584 ~hostArray();
00585 bool Insert(const char *match_data_in, HostBranch * toInsert);
00586 HostBranch *Lookup(const char *match_data_in, bool bNotProcess);
00587 HostBranch *iter_first(hostArrayIterState * s, char **key = NULL);
00588 HostBranch *iter_next(hostArrayIterState * s, char **key = NULL);
00589 private:
00590 int num_el;
00591 HostBranch *branch_array[HOST_ARRAY_MAX];
00592 char *match_data[HOST_ARRAY_MAX];
00593 };
00594
00595 hostArray::hostArray():num_el(0)
00596 {
00597 memset(branch_array, 0, sizeof(branch_array));
00598 memset(match_data, 0, sizeof(match_data));
00599 }
00600
00601 hostArray::~hostArray()
00602 {
00603 for (int i = 0; i < num_el; i++) {
00604 ink_assert(branch_array[i] != NULL);
00605 ink_assert(match_data[i] != NULL);
00606 ats_free(match_data[i]);
00607 }
00608 }
00609
00610
00611
00612
00613
00614
00615
00616 bool
00617 hostArray::Insert(const char *match_data_in, HostBranch * toInsert)
00618 {
00619 if (num_el >= HOST_ARRAY_MAX) {
00620 return false;
00621 } else {
00622 branch_array[num_el] = toInsert;
00623 match_data[num_el] = ats_strdup(match_data_in);
00624 num_el++;
00625 return true;
00626 }
00627 }
00628
00629
00630
00631
00632
00633
00634
00635 HostBranch *
00636 hostArray::Lookup(const char *match_data_in, bool bNotProcess)
00637 {
00638 HostBranch *r = NULL;
00639 char *pMD;
00640
00641 for (int i = 0; i < num_el; i++) {
00642 pMD = match_data[i];
00643
00644 if (bNotProcess && '!' == *pMD) {
00645
00646 char *cp = ++pMD;
00647 if ('\0' == *cp)
00648 continue;
00649
00650 if (strcmp(cp, match_data_in) != 0) {
00651 r = branch_array[i];
00652 } else {
00653 continue;
00654 }
00655 }
00656
00657 else if (strcmp(match_data[i], match_data_in) == 0) {
00658 r = branch_array[i];
00659 break;
00660 }
00661 }
00662 return r;
00663 }
00664
00665
00666
00667
00668
00669
00670 HostBranch *
00671 hostArray::iter_first(hostArrayIterState * s, char **key)
00672 {
00673 *s = -1;
00674 return iter_next(s, key);
00675 }
00676
00677
00678
00679
00680
00681
00682 HostBranch *
00683 hostArray::iter_next(hostArrayIterState * s, char **key)
00684 {
00685 (*s)++;
00686
00687 if (*s < num_el) {
00688 if (key != NULL) {
00689 *key = match_data[*s];
00690 }
00691 return branch_array[*s];
00692 } else {
00693 return NULL;
00694 }
00695 }
00696
00697
00698 const char *LeafTypeStr[] = {
00699 "Leaf Invalid",
00700 "Host (Partial)",
00701 "Host (Full)",
00702 "Domain (Full)",
00703 "Domain (Partial)"
00704 };
00705
00706 static int negative_one = -1;
00707
00708 HostBranch::HostBranch():level(0), type(HOST_TERMINAL), next_level(NULL), leaf_indexs(&negative_one, 1)
00709 {
00710 }
00711
00712
00713
00714
00715
00716 HostBranch::~HostBranch()
00717 {
00718
00719
00720 InkHashTable *ht;
00721 InkHashTableIteratorState ht_iter;
00722 InkHashTableEntry *ht_entry = NULL;
00723
00724
00725 charIndexIterState ci_iter;
00726 charIndex *ci;
00727
00728
00729 hostArray *ha;
00730 hostArrayIterState ha_iter;
00731
00732 HostBranch *lower_branch;
00733
00734 switch (type) {
00735 case HOST_TERMINAL:
00736 ink_assert(next_level == NULL);
00737 break;
00738 case HOST_HASH:
00739 ink_assert(next_level != NULL);
00740 ht = (InkHashTable *) next_level;
00741 ht_entry = ink_hash_table_iterator_first(ht, &ht_iter);
00742
00743 while (ht_entry != NULL) {
00744 lower_branch = (HostBranch *) ink_hash_table_entry_value(ht, ht_entry);
00745 delete lower_branch;
00746 ht_entry = ink_hash_table_iterator_next(ht, &ht_iter);
00747 }
00748 ink_hash_table_destroy(ht);
00749 break;
00750 case HOST_INDEX:
00751 ink_assert(next_level != NULL);
00752 ci = (charIndex *) next_level;
00753 lower_branch = ci->iter_first(&ci_iter);
00754 while (lower_branch != NULL) {
00755 delete lower_branch;
00756 lower_branch = ci->iter_next(&ci_iter);
00757 }
00758 delete ci;
00759 break;
00760 case HOST_ARRAY:
00761 ink_assert(next_level != NULL);
00762 ha = (hostArray *) next_level;
00763 lower_branch = ha->iter_first(&ha_iter);
00764 while (lower_branch != NULL) {
00765 delete lower_branch;
00766 lower_branch = ha->iter_next(&ha_iter);
00767 }
00768 delete ha;
00769 break;
00770 }
00771 }
00772
00773 HostLookup::HostLookup(const char *name):
00774 leaf_array(NULL),
00775 array_len(-1),
00776 num_el(-1),
00777 matcher_name(name)
00778 {
00779
00780 root = new HostBranch;
00781 root->level = 0;
00782 root->type = HOST_TERMINAL;
00783 root->next_level = NULL;
00784 }
00785
00786 HostLookup::~HostLookup()
00787 {
00788
00789 if (leaf_array != NULL) {
00790
00791 for (int i = 0; i < num_el; i++) {
00792 ats_free(leaf_array[i].match);
00793 }
00794 delete[]leaf_array;
00795 }
00796
00797 delete root;
00798 }
00799
00800 static void
00801 empty_print_fn(void *)
00802 {
00803 }
00804
00805 void
00806 HostLookup::Print()
00807 {
00808 Print(empty_print_fn);
00809 }
00810
00811 void
00812 HostLookup::Print(HostLookupPrintFunc f)
00813 {
00814 PrintHostBranch(root, f);
00815 }
00816
00817
00818
00819
00820
00821
00822
00823 void
00824 HostLookup::PrintHostBranch(HostBranch * hb, HostLookupPrintFunc f)
00825 {
00826
00827
00828 InkHashTable *ht;
00829 InkHashTableIteratorState ht_iter;
00830 InkHashTableEntry *ht_entry = NULL;
00831
00832
00833 charIndexIterState ci_iter;
00834 charIndex *ci;
00835
00836
00837 hostArray *h_array;
00838 hostArrayIterState ha_iter;
00839
00840 HostBranch *lower_branch;
00841 intptr_t curIndex;
00842 intptr_t i;
00843
00844 for (i = 0; i < hb->leaf_indexs.length(); i++) {
00845 curIndex = hb->leaf_indexs[i];
00846 printf("\t\t%s for %s\n", LeafTypeStr[leaf_array[curIndex].type], leaf_array[curIndex].match);
00847 f(leaf_array[curIndex].opaque_data);
00848 }
00849
00850 switch (hb->type) {
00851 case HOST_TERMINAL:
00852 ink_assert(hb->next_level == NULL);
00853 break;
00854 case HOST_HASH:
00855 ink_assert(hb->next_level != NULL);
00856 ht = (InkHashTable *) hb->next_level;
00857 ht_entry = ink_hash_table_iterator_first(ht, &ht_iter);
00858
00859 while (ht_entry != NULL) {
00860 lower_branch = (HostBranch *) ink_hash_table_entry_value(ht, ht_entry);
00861 PrintHostBranch(lower_branch, f);
00862 ht_entry = ink_hash_table_iterator_next(ht, &ht_iter);
00863 }
00864 break;
00865 case HOST_INDEX:
00866 ink_assert(hb->next_level != NULL);
00867 ci = (charIndex *) hb->next_level;
00868 lower_branch = ci->iter_first(&ci_iter);
00869 while (lower_branch != NULL) {
00870 PrintHostBranch(lower_branch, f);
00871 lower_branch = ci->iter_next(&ci_iter);
00872 }
00873 break;
00874 case HOST_ARRAY:
00875 ink_assert(hb->next_level != NULL);
00876 h_array = (hostArray *) hb->next_level;
00877 lower_branch = h_array->iter_first(&ha_iter);
00878 while (lower_branch != NULL) {
00879 PrintHostBranch(lower_branch, f);
00880 lower_branch = h_array->iter_next(&ha_iter);
00881 }
00882 break;
00883 }
00884 }
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 HostBranch *
00895 HostLookup::TableNewLevel(HostBranch * from, const char *level_data)
00896 {
00897 hostArray *new_ha_table;
00898 charIndex *new_ci_table;
00899
00900 ink_assert(from->type == HOST_TERMINAL);
00901
00902
00903
00904 if (from->level == 0) {
00905 new_ci_table = new charIndex;
00906 from->type = HOST_INDEX;
00907 from->next_level = new_ci_table;
00908 } else {
00909 new_ha_table = new hostArray;
00910 from->type = HOST_ARRAY;
00911 from->next_level = new_ha_table;
00912 }
00913
00914 return InsertBranch(from, level_data);
00915 }
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926 HostBranch *
00927 HostLookup::InsertBranch(HostBranch * insert_in, const char *level_data)
00928 {
00929
00930
00931
00932
00933 hostArray *ha;
00934 hostArrayIterState ha_iter;
00935 HostBranch *tmp;
00936 char *key = NULL;
00937 InkHashTable *new_ht;
00938
00939
00940 HostBranch *new_branch = new HostBranch;
00941 new_branch->type = HOST_TERMINAL;
00942 new_branch->level = insert_in->level + 1;
00943 new_branch->next_level = NULL;
00944
00945 switch (insert_in->type) {
00946 case HOST_TERMINAL:
00947
00948 ink_release_assert(0);
00949 break;
00950 case HOST_HASH:
00951 ink_hash_table_insert((InkHashTable *) insert_in->next_level, (char *) level_data, new_branch);
00952 break;
00953 case HOST_INDEX:
00954 ((charIndex *) insert_in->next_level)->Insert(level_data, new_branch);
00955 break;
00956 case HOST_ARRAY:
00957 if (((hostArray *) insert_in->next_level)->Insert(level_data, new_branch) == false) {
00958
00959
00960 ha = (hostArray *) insert_in->next_level;
00961 new_ht = ink_hash_table_create(InkHashTableKeyType_String);
00962 ink_hash_table_insert(new_ht, (char *) level_data, new_branch);
00963
00964
00965
00966 tmp = ha->iter_first(&ha_iter, &key);
00967 ink_assert(tmp != NULL);
00968 while (tmp != NULL) {
00969 ink_assert(key != NULL);
00970 ink_hash_table_insert(new_ht, key, tmp);
00971 tmp = ha->iter_next(&ha_iter, &key);
00972 }
00973
00974
00975 delete ha;
00976 insert_in->next_level = new_ht;
00977 insert_in->type = HOST_HASH;
00978 }
00979 break;
00980
00981 }
00982
00983 return new_branch;
00984 }
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994 HostBranch *
00995 HostLookup::FindNextLevel(HostBranch * from, const char *level_data, bool bNotProcess)
00996 {
00997
00998 HostBranch *r = NULL;
00999 InkHashTable *hash;
01000 charIndex *ci_table;
01001 hostArray *ha_table;
01002 void *lookup;
01003
01004 switch (from->type) {
01005 case HOST_TERMINAL:
01006
01007 ink_assert(0);
01008 return NULL;
01009 case HOST_HASH:
01010 hash = (InkHashTable *) from->next_level;
01011 ink_assert(hash != NULL);
01012 if (ink_hash_table_lookup(hash, (char *) level_data, &lookup)) {
01013 r = (HostBranch *) lookup;
01014 } else {
01015 r = NULL;
01016 }
01017 break;
01018 case HOST_INDEX:
01019 ci_table = (charIndex *) from->next_level;
01020 ink_assert(ci_table != NULL);
01021 r = ci_table->Lookup(level_data);
01022 break;
01023 case HOST_ARRAY:
01024 ha_table = (hostArray *) from->next_level;
01025 ink_assert(ha_table != NULL);
01026 r = ha_table->Lookup(level_data, bNotProcess);
01027 break;
01028 }
01029 return r;
01030 }
01031
01032
01033
01034
01035
01036
01037
01038
01039 void
01040 HostLookup::TableInsert(const char *match_data, int index, bool domain_record)
01041 {
01042 HostBranch *cur = this->root;
01043 HostBranch *next;
01044 char *match_copy = ats_strdup(match_data);
01045 Tokenizer match_tok(".");
01046 int numTok;
01047 int i;
01048
01049 LowerCaseStr(match_copy);
01050 numTok = match_tok.Initialize(match_copy, SHARE_TOKS);
01051
01052
01053
01054
01055
01056 for (i = 0; i < HOST_TABLE_DEPTH; i++) {
01057
01058
01059 if (numTok == cur->level) {
01060 break;
01061 }
01062
01063 if (cur->next_level == NULL) {
01064 cur = TableNewLevel(cur, match_tok[numTok - i - 1]);
01065 } else {
01066 next = FindNextLevel(cur, match_tok[numTok - i - 1]);
01067 if (next == NULL) {
01068 cur = InsertBranch(cur, match_tok[numTok - i - 1]);
01069 } else {
01070 cur = next;
01071 }
01072 }
01073 }
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091 if (domain_record == false) {
01092 if (numTok > HOST_TABLE_DEPTH) {
01093 leaf_array[index].type = HOST_PARTIAL;
01094 } else {
01095 leaf_array[index].type = HOST_COMPLETE;
01096 }
01097 } else {
01098 if (numTok > HOST_TABLE_DEPTH) {
01099 leaf_array[index].type = DOMAIN_PARTIAL;
01100 } else {
01101 leaf_array[index].type = DOMAIN_COMPLETE;
01102 }
01103 }
01104
01105
01106
01107 cur->leaf_indexs(cur->leaf_indexs.length()) = index;
01108
01109 ats_free(match_copy);
01110 }
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124 bool
01125 HostLookup::MatchArray(HostLookupState * s, void **opaque_ptr, DynArray<int>&array, bool host_done)
01126 {
01127 intptr_t index;
01128 intptr_t i;
01129
01130 for (i = s->array_index + 1; i < array.length(); i++) {
01131 index = array[i];
01132
01133 switch (leaf_array[index].type) {
01134 case HOST_PARTIAL:
01135 if (hostcmp(s->hostname, leaf_array[index].match) == 0) {
01136 *opaque_ptr = leaf_array[index].opaque_data;
01137 s->array_index = i;
01138 return true;
01139 }
01140 break;
01141 case HOST_COMPLETE:
01142
01143
01144
01145
01146 if (host_done == true) {
01147 *opaque_ptr = leaf_array[index].opaque_data;
01148 s->array_index = i;
01149 return true;
01150 }
01151 break;
01152 case DOMAIN_PARTIAL:
01153 if (domaincmp(s->hostname, leaf_array[index].match) == false) {
01154 break;
01155 }
01156
01157 case DOMAIN_COMPLETE:
01158 *opaque_ptr = leaf_array[index].opaque_data;
01159 s->array_index = i;
01160 return true;
01161 case LEAF_INVALID:
01162
01163 ink_assert(0);
01164 break;
01165 }
01166 }
01167
01168 s->array_index = i;
01169 return false;
01170 }
01171
01172
01173
01174
01175
01176 bool
01177 HostLookup::MatchFirst(const char *host, HostLookupState * s, void **opaque_ptr)
01178 {
01179 char *last_dot = NULL;
01180
01181 s->cur = root;
01182 s->table_level = 0;
01183 s->array_index = -1;
01184 s->hostname = host ? host : "";
01185 s->host_copy = ats_strdup(s->hostname);
01186 LowerCaseStr(s->host_copy);
01187
01188
01189 s->host_copy_next = s->host_copy;
01190 while (*s->host_copy_next != '\0') {
01191 if (*s->host_copy_next == '.') {
01192 last_dot = s->host_copy_next;
01193 }
01194 s->host_copy_next++;
01195 }
01196
01197 if (last_dot == NULL) {
01198
01199 s->host_copy_next = s->host_copy;
01200 } else {
01201 s->host_copy_next = last_dot + 1;
01202 }
01203
01204 return MatchNext(s, opaque_ptr);
01205 }
01206
01207
01208
01209
01210
01211
01212 bool
01213 HostLookup::MatchNext(HostLookupState * s, void **opaque_ptr)
01214 {
01215 HostBranch *cur = s->cur;
01216
01217
01218 if (num_el <= 0) {
01219 return false;
01220 }
01221
01222 while (s->table_level <= HOST_TABLE_DEPTH) {
01223
01224 if (MatchArray(s, opaque_ptr, cur->leaf_indexs, (s->host_copy_next == NULL))) {
01225 return true;
01226 }
01227
01228 if (s->host_copy_next == NULL) {
01229 break;
01230 }
01231
01232 if (cur->type == HOST_TERMINAL) {
01233 break;
01234 }
01235
01236 cur = FindNextLevel(cur, s->host_copy_next, true);
01237
01238 if (cur == NULL) {
01239 break;
01240 } else {
01241 s->cur = cur;
01242 s->array_index = -1;
01243 s->table_level++;
01244
01245
01246 if (s->host_copy_next <= s->host_copy) {
01247
01248 s->host_copy_next = NULL;
01249 } else {
01250
01251
01252 s->host_copy_next--;
01253 ink_assert(*s->host_copy_next == '.');
01254 *s->host_copy_next = '\0';
01255
01256 s->host_copy_next--;
01257
01258 while (1) {
01259
01260 if (s->host_copy_next <= s->host_copy) {
01261 s->host_copy_next = s->host_copy;
01262 break;
01263 }
01264
01265
01266
01267 if (*s->host_copy_next == '.') {
01268 s->host_copy_next++;
01269 break;
01270 }
01271
01272 s->host_copy_next--;
01273 }
01274 }
01275 }
01276 }
01277
01278 return false;
01279 }
01280
01281
01282
01283
01284
01285 void
01286 HostLookup::AllocateSpace(int num_entries)
01287 {
01288
01289 ink_assert(array_len == -1);
01290
01291 leaf_array = new HostLeaf[num_entries];
01292 memset(leaf_array, 0, sizeof(HostLeaf) * num_entries);
01293
01294 array_len = num_entries;
01295 num_el = 0;
01296 }
01297
01298
01299
01300
01301
01302 void
01303 HostLookup::NewEntry(const char *match_data, bool domain_record, void *opaque_data_in)
01304 {
01305
01306
01307 ink_assert(num_el >= 0);
01308 ink_assert(array_len >= 0);
01309
01310
01311 ink_assert(num_el < array_len);
01312
01313 leaf_array[num_el].match = ats_strdup(match_data);
01314 leaf_array[num_el].opaque_data = opaque_data_in;
01315
01316 if ('!' != *(leaf_array[num_el].match)) {
01317 leaf_array[num_el].len = strlen(match_data);
01318 leaf_array[num_el].isNot = false;
01319 } else {
01320 leaf_array[num_el].len = strlen(match_data) - 1;
01321 leaf_array[num_el].isNot = true;
01322 }
01323
01324 TableInsert(match_data, num_el, domain_record);
01325 num_el++;
01326 }