diff options
author | Peter Palfrader <peter@palfrader.org> | 2008-08-13 12:45:09 +0000 |
---|---|---|
committer | Peter Palfrader <peter@palfrader.org> | 2008-08-13 12:45:09 +0000 |
commit | 1adc12546ee920f33389fef65a19435c92fecf9a (patch) | |
tree | e2a80663c950a525ae2b7895975c00afcbd18e2c /src/or/policies.c | |
parent | f5adde1a175588cf4c85c2d5be8b5db66683e430 (diff) | |
download | tor-1adc12546ee920f33389fef65a19435c92fecf9a.tar.gz tor-1adc12546ee920f33389fef65a19435c92fecf9a.zip |
implement policy_summary_accept and policy_summary_reject together with a set of helpers
svn:r16519
Diffstat (limited to 'src/or/policies.c')
-rw-r--r-- | src/or/policies.c | 95 |
1 files changed, 83 insertions, 12 deletions
diff --git a/src/or/policies.c b/src/or/policies.c index 07b5b6715c..dd0f24fd52 100644 --- a/src/or/policies.c +++ b/src/or/policies.c @@ -917,13 +917,16 @@ typedef struct policy_summary_item_t { uint16_t prt_max; /**< Highest port number to accept/reject. */ uint64_t reject_count; /**< Number of IP-Addresses that are rejected to this portrange. */ + int accepted:1; /** Has this port already been accepted */ } policy_summary_item_t; smartlist_t *policy_summary_create(void); void policy_summary_accept(smartlist_t *summary, uint16_t prt_min, uint16_t prt_max); -void policy_summary_reject(smartlist_t *summary, uint16_t prt_min, uint16_t prt_max); +void policy_summary_reject(smartlist_t *summary, maskbits_t maskbits, uint16_t prt_min, uint16_t prt_max); void policy_summary_add_item(smartlist_t *summary, addr_policy_t *p); void policy_summarize(smartlist_t *policy); +int policy_summary_split(smartlist_t *summary, uint16_t prt_min, uint16_t prt_max); +policy_summary_item_t* policy_summary_item_split(policy_summary_item_t* old, uint16_t new_starts); /** Create a new exit policy summary, initially only with a single * port 1-64k item */ @@ -937,6 +940,7 @@ policy_summary_create(void) item->prt_min = 1; item->prt_max = 65535; item->reject_count = 0; + item->accepted = 0; summary = smartlist_create(); smartlist_add(summary, item); @@ -944,24 +948,91 @@ policy_summary_create(void) return summary; } +/** Split the summary item in <b>item</b> at the port <b>new_starts</b>. + * The current item is changed to end at new-starts - 1, the new item + * copies reject_count and accepted from the old item, + * starts at new_starts and ends at the port where the original item + * previously ended. + */ +policy_summary_item_t* +policy_summary_item_split(policy_summary_item_t* old, uint16_t new_starts) { + policy_summary_item_t* new; + + new = tor_malloc_zero(sizeof(policy_summary_item_t)); + new->prt_min = new_starts; + new->prt_max = old->prt_max; + new->reject_count = old->reject_count; + new->accepted = old->accepted; + + old->prt_max = new_starts-1; + + tor_assert(old->prt_min < old->prt_max); + tor_assert(new->prt_min < new->prt_max); + return new; +} + +#define AT(x) ((policy_summary_item_t*)smartlist_get(summary, x)) +#define REJECT_CUTOFF_COUNT (1<<25) +/* Split an exit policy summary so that prt_min and prt_max + * fall at exactly the start and end of an item respectively. + */ +int +policy_summary_split(smartlist_t *summary, + uint16_t prt_min, uint16_t prt_max) +{ + int start_at_index; + + int i = 0; + while (AT(i)->prt_max < prt_min) + i++; + if (AT(i)->prt_min != prt_min) { + policy_summary_item_t* new_item; + new_item = policy_summary_item_split(AT(i), prt_min); + smartlist_insert(summary, i+1, new_item); + i++; + } + start_at_index = i; + + while(AT(i)->prt_max < prt_max) + i++; + if (AT(i)->prt_max != prt_max) { + policy_summary_item_t* new_item; + new_item = policy_summary_item_split(AT(i), prt_max+1); + smartlist_insert(summary, i+1, new_item); + } + + return start_at_index; +} + +/** Mark port ranges as accepted if they are below the reject_count */ void -policy_summary_accept(smartlist_t *summary, +policy_summary_accept(smartlist_t *summary, uint16_t prt_min, uint16_t prt_max) { - /* XXX */ - (void) summary; - (void) prt_min; - (void) prt_max; + int i = policy_summary_split(summary, prt_min, prt_max); + while (AT(i)->prt_max <= prt_max) { + if (AT(i)->accepted || + AT(i)->reject_count > REJECT_CUTOFF_COUNT) + continue; + AT(i)->accepted = 1; + i++; + } } +/** Count the number of addresses in a network with prefixlen maskbits + * against the given portrange. */ void -policy_summary_reject(smartlist_t *summary, +policy_summary_reject(smartlist_t *summary, + maskbits_t maskbits, uint16_t prt_min, uint16_t prt_max) { - /* XXX */ - (void) summary; - (void) prt_min; - (void) prt_max; + int i = policy_summary_split(summary, prt_min, prt_max); + /* XXX: ipv4 specific */ + int count = (1 << (32-maskbits)); + while (AT(i)->prt_max <= prt_max) { + AT(i)->reject_count += count; + i++; + } } /** Add a single exit policy item to our summary */ @@ -991,7 +1062,7 @@ policy_summary_add_item(smartlist_t *summary, addr_policy_t *p) } if (!is_private) { - policy_summary_reject(summary, p->prt_min, p->prt_max); + policy_summary_reject(summary, p->maskbits, p->prt_min, p->prt_max); } } else tor_assert(0); |