| 24 |
|
|
| 25 |
|
#include "stdinc.h" |
| 26 |
|
#include "list.h" |
| 27 |
– |
#include "balloc.h" |
| 27 |
|
#include "conf.h" |
| 28 |
|
#include "channel.h" |
| 29 |
|
#include "channel_mode.h" |
| 38 |
|
#include "numeric.h" |
| 39 |
|
#include "send.h" |
| 40 |
|
#include "memory.h" |
| 41 |
+ |
#include "mempool.h" |
| 42 |
|
#include "dbuf.h" |
| 43 |
|
#include "s_user.h" |
| 44 |
|
|
| 45 |
|
|
| 46 |
< |
static BlockHeap *userhost_heap = NULL; |
| 47 |
< |
static BlockHeap *namehost_heap = NULL; |
| 48 |
< |
static struct UserHost *find_or_add_userhost(const char *); |
| 46 |
> |
static mp_pool_t *userhost_pool = NULL; |
| 47 |
> |
static mp_pool_t *namehost_pool = NULL; |
| 48 |
|
|
| 49 |
|
static unsigned int hashf_xor_key = 0; |
| 50 |
|
|
| 57 |
|
static struct Client *clientTable[HASHSIZE]; |
| 58 |
|
static struct Channel *channelTable[HASHSIZE]; |
| 59 |
|
static struct UserHost *userhostTable[HASHSIZE]; |
| 61 |
– |
static struct ResvChannel *resvchannelTable[HASHSIZE]; |
| 60 |
|
|
| 61 |
|
|
| 62 |
|
/* init_hash() |
| 67 |
|
* functions and clear the tables |
| 68 |
|
*/ |
| 69 |
|
void |
| 70 |
< |
init_hash(void) |
| 70 |
> |
hash_init(void) |
| 71 |
|
{ |
| 72 |
< |
unsigned int i; |
| 73 |
< |
|
| 76 |
< |
/* Default the userhost/namehost sizes to CLIENT_HEAP_SIZE for now, |
| 77 |
< |
* should be a good close approximation anyway |
| 78 |
< |
* - Dianora |
| 79 |
< |
*/ |
| 80 |
< |
userhost_heap = BlockHeapCreate("userhost", sizeof(struct UserHost), CLIENT_HEAP_SIZE); |
| 81 |
< |
namehost_heap = BlockHeapCreate("namehost", sizeof(struct NameHost), CLIENT_HEAP_SIZE); |
| 72 |
> |
userhost_pool = mp_pool_new(sizeof(struct UserHost), MP_CHUNK_SIZE_USERHOST); |
| 73 |
> |
namehost_pool = mp_pool_new(sizeof(struct NameHost), MP_CHUNK_SIZE_NAMEHOST); |
| 74 |
|
|
| 75 |
|
hashf_xor_key = genrand_int32() % 256; /* better than nothing --adx */ |
| 76 |
|
} |
| 88 |
|
const unsigned char *p = (const unsigned char *)name; |
| 89 |
|
unsigned int hval = FNV1_32_INIT; |
| 90 |
|
|
| 91 |
< |
if (*p == '\0') |
| 91 |
> |
if (EmptyString(p)) |
| 92 |
|
return 0; |
| 93 |
|
for (; *p != '\0'; ++p) |
| 94 |
|
{ |
| 148 |
|
} |
| 149 |
|
|
| 150 |
|
void |
| 159 |
– |
hash_add_resv(struct ResvChannel *chptr) |
| 160 |
– |
{ |
| 161 |
– |
unsigned int hashv = strhash(chptr->name); |
| 162 |
– |
|
| 163 |
– |
chptr->hnext = resvchannelTable[hashv]; |
| 164 |
– |
resvchannelTable[hashv] = chptr; |
| 165 |
– |
} |
| 166 |
– |
|
| 167 |
– |
void |
| 151 |
|
hash_add_userhost(struct UserHost *userhost) |
| 152 |
|
{ |
| 153 |
|
unsigned int hashv = strhash(userhost->host); |
| 290 |
|
} |
| 291 |
|
} |
| 292 |
|
|
| 310 |
– |
void |
| 311 |
– |
hash_del_resv(struct ResvChannel *chptr) |
| 312 |
– |
{ |
| 313 |
– |
unsigned int hashv = strhash(chptr->name); |
| 314 |
– |
struct ResvChannel *tmp = resvchannelTable[hashv]; |
| 315 |
– |
|
| 316 |
– |
if (tmp != NULL) |
| 317 |
– |
{ |
| 318 |
– |
if (tmp == chptr) |
| 319 |
– |
{ |
| 320 |
– |
resvchannelTable[hashv] = chptr->hnext; |
| 321 |
– |
chptr->hnext = chptr; |
| 322 |
– |
} |
| 323 |
– |
else |
| 324 |
– |
{ |
| 325 |
– |
while (tmp->hnext != chptr) |
| 326 |
– |
if ((tmp = tmp->hnext) == NULL) |
| 327 |
– |
return; |
| 328 |
– |
|
| 329 |
– |
tmp->hnext = tmp->hnext->hnext; |
| 330 |
– |
chptr->hnext = chptr; |
| 331 |
– |
} |
| 332 |
– |
} |
| 333 |
– |
} |
| 334 |
– |
|
| 293 |
|
/* hash_find_client() |
| 294 |
|
* |
| 295 |
|
* inputs - pointer to name |
| 361 |
|
struct Client *client_p = NULL; |
| 362 |
|
|
| 363 |
|
if (IsDigit(*name) && strlen(name) == IRC_MAXSID) |
| 364 |
< |
client_p = hash_find_id(name); |
| 364 |
> |
return hash_find_id(name); |
| 365 |
|
|
| 366 |
< |
if ((client_p == NULL) && (client_p = clientTable[hashv]) != NULL) |
| 366 |
> |
if ((client_p = clientTable[hashv]) != NULL) |
| 367 |
|
{ |
| 368 |
|
if ((!IsServer(client_p) && !IsMe(client_p)) || |
| 369 |
|
irccmp(name, client_p->name)) |
| 454 |
|
case HASH_TYPE_USERHOST: |
| 455 |
|
return userhostTable[hashv]; |
| 456 |
|
break; |
| 499 |
– |
case HASH_TYPE_RESERVED: |
| 500 |
– |
return resvchannelTable[hashv]; |
| 501 |
– |
break; |
| 457 |
|
default: |
| 458 |
|
assert(0); |
| 459 |
|
} |
| 461 |
|
return NULL; |
| 462 |
|
} |
| 463 |
|
|
| 509 |
– |
/* hash_find_resv() |
| 510 |
– |
* |
| 511 |
– |
* inputs - pointer to name |
| 512 |
– |
* output - NONE |
| 513 |
– |
* side effects - New semantics: finds a reserved channel whose name is 'name', |
| 514 |
– |
* if can't find one returns NULL, if can find it moves |
| 515 |
– |
* it to the top of the list and returns it. |
| 516 |
– |
*/ |
| 517 |
– |
struct ResvChannel * |
| 518 |
– |
hash_find_resv(const char *name) |
| 519 |
– |
{ |
| 520 |
– |
unsigned int hashv = strhash(name); |
| 521 |
– |
struct ResvChannel *chptr; |
| 522 |
– |
|
| 523 |
– |
if ((chptr = resvchannelTable[hashv]) != NULL) |
| 524 |
– |
{ |
| 525 |
– |
if (irccmp(name, chptr->name)) |
| 526 |
– |
{ |
| 527 |
– |
struct ResvChannel *prev; |
| 528 |
– |
|
| 529 |
– |
while (prev = chptr, (chptr = chptr->hnext) != NULL) |
| 530 |
– |
{ |
| 531 |
– |
if (!irccmp(name, chptr->name)) |
| 532 |
– |
{ |
| 533 |
– |
prev->hnext = chptr->hnext; |
| 534 |
– |
chptr->hnext = resvchannelTable[hashv]; |
| 535 |
– |
resvchannelTable[hashv] = chptr; |
| 536 |
– |
break; |
| 537 |
– |
} |
| 538 |
– |
} |
| 539 |
– |
} |
| 540 |
– |
} |
| 541 |
– |
|
| 542 |
– |
return chptr; |
| 543 |
– |
} |
| 544 |
– |
|
| 464 |
|
struct UserHost * |
| 465 |
|
hash_find_userhost(const char *host) |
| 466 |
|
{ |
| 501 |
|
* side effects - |
| 502 |
|
*/ |
| 503 |
|
void |
| 504 |
< |
count_user_host(const char *user, const char *host, int *global_p, |
| 505 |
< |
int *local_p, int *icount_p) |
| 504 |
> |
count_user_host(const char *user, const char *host, unsigned int *global_p, |
| 505 |
> |
unsigned int *local_p, unsigned int *icount_p) |
| 506 |
|
{ |
| 507 |
|
dlink_node *ptr; |
| 508 |
|
struct UserHost *found_userhost; |
| 528 |
|
} |
| 529 |
|
} |
| 530 |
|
|
| 531 |
+ |
/* find_or_add_userhost() |
| 532 |
+ |
* |
| 533 |
+ |
* inputs - host name |
| 534 |
+ |
* output - none |
| 535 |
+ |
* side effects - find UserHost * for given host name |
| 536 |
+ |
*/ |
| 537 |
+ |
static struct UserHost * |
| 538 |
+ |
find_or_add_userhost(const char *host) |
| 539 |
+ |
{ |
| 540 |
+ |
struct UserHost *userhost; |
| 541 |
+ |
|
| 542 |
+ |
if ((userhost = hash_find_userhost(host)) != NULL) |
| 543 |
+ |
return userhost; |
| 544 |
+ |
|
| 545 |
+ |
userhost = mp_pool_get(userhost_pool); |
| 546 |
+ |
|
| 547 |
+ |
memset(userhost, 0, sizeof(*userhost)); |
| 548 |
+ |
strlcpy(userhost->host, host, sizeof(userhost->host)); |
| 549 |
+ |
hash_add_userhost(userhost); |
| 550 |
+ |
|
| 551 |
+ |
return userhost; |
| 552 |
+ |
} |
| 553 |
+ |
|
| 554 |
|
/* add_user_host() |
| 555 |
|
* |
| 556 |
|
* inputs - user name |
| 583 |
|
if (!irccmp(user, nameh->name)) |
| 584 |
|
{ |
| 585 |
|
nameh->gcount++; |
| 586 |
+ |
|
| 587 |
|
if (!global) |
| 588 |
|
{ |
| 589 |
< |
if (hasident) |
| 590 |
< |
nameh->icount++; |
| 591 |
< |
nameh->lcount++; |
| 589 |
> |
if (hasident) |
| 590 |
> |
nameh->icount++; |
| 591 |
> |
nameh->lcount++; |
| 592 |
|
} |
| 593 |
+ |
|
| 594 |
|
return; |
| 595 |
|
} |
| 596 |
|
} |
| 597 |
|
|
| 598 |
< |
nameh = BlockHeapAlloc(namehost_heap); |
| 598 |
> |
nameh = mp_pool_get(namehost_pool); |
| 599 |
> |
memset(nameh, 0, sizeof(*nameh)); |
| 600 |
|
strlcpy(nameh->name, user, sizeof(nameh->name)); |
| 601 |
|
|
| 602 |
|
nameh->gcount = 1; |
| 603 |
+ |
|
| 604 |
|
if (!global) |
| 605 |
|
{ |
| 606 |
|
if (hasident) |
| 646 |
|
nameh->gcount--; |
| 647 |
|
if (!global) |
| 648 |
|
{ |
| 649 |
< |
if (nameh->lcount > 0) |
| 650 |
< |
nameh->lcount--; |
| 651 |
< |
if (hasident && nameh->icount > 0) |
| 652 |
< |
nameh->icount--; |
| 649 |
> |
if (nameh->lcount > 0) |
| 650 |
> |
nameh->lcount--; |
| 651 |
> |
if (hasident && nameh->icount > 0) |
| 652 |
> |
nameh->icount--; |
| 653 |
|
} |
| 654 |
|
|
| 655 |
|
if (nameh->gcount == 0 && nameh->lcount == 0) |
| 656 |
|
{ |
| 657 |
< |
dlinkDelete(&nameh->node, &found_userhost->list); |
| 658 |
< |
BlockHeapFree(namehost_heap, nameh); |
| 657 |
> |
dlinkDelete(&nameh->node, &found_userhost->list); |
| 658 |
> |
mp_pool_release(nameh); |
| 659 |
|
} |
| 660 |
|
|
| 661 |
|
if (dlink_list_length(&found_userhost->list) == 0) |
| 662 |
|
{ |
| 663 |
< |
hash_del_userhost(found_userhost); |
| 664 |
< |
BlockHeapFree(userhost_heap, found_userhost); |
| 663 |
> |
hash_del_userhost(found_userhost); |
| 664 |
> |
mp_pool_release(found_userhost); |
| 665 |
|
} |
| 666 |
|
|
| 667 |
|
return; |
| 669 |
|
} |
| 670 |
|
} |
| 671 |
|
|
| 726 |
– |
/* find_or_add_userhost() |
| 727 |
– |
* |
| 728 |
– |
* inputs - host name |
| 729 |
– |
* output - none |
| 730 |
– |
* side effects - find UserHost * for given host name |
| 731 |
– |
*/ |
| 732 |
– |
static struct UserHost * |
| 733 |
– |
find_or_add_userhost(const char *host) |
| 734 |
– |
{ |
| 735 |
– |
struct UserHost *userhost; |
| 736 |
– |
|
| 737 |
– |
if ((userhost = hash_find_userhost(host)) != NULL) |
| 738 |
– |
return userhost; |
| 739 |
– |
|
| 740 |
– |
userhost = BlockHeapAlloc(userhost_heap); |
| 741 |
– |
strlcpy(userhost->host, host, sizeof(userhost->host)); |
| 742 |
– |
hash_add_userhost(userhost); |
| 743 |
– |
|
| 744 |
– |
return userhost; |
| 745 |
– |
} |
| 746 |
– |
|
| 672 |
|
/* |
| 673 |
|
* Safe list code. |
| 674 |
|
* |
| 694 |
|
static int |
| 695 |
|
exceeding_sendq(struct Client *to) |
| 696 |
|
{ |
| 697 |
< |
if (dbuf_length(&to->localClient->buf_sendq) > (get_sendq(to) / 2)) |
| 697 |
> |
if (dbuf_length(&to->localClient->buf_sendq) > (get_sendq(&to->localClient->confs) / 2)) |
| 698 |
|
return 1; |
| 699 |
|
else |
| 700 |
|
return 0; |
| 703 |
|
void |
| 704 |
|
free_list_task(struct ListTask *lt, struct Client *source_p) |
| 705 |
|
{ |
| 706 |
< |
dlink_node *dl, *dln; |
| 706 |
> |
dlink_node *dl = NULL, *dln = NULL; |
| 707 |
|
|
| 708 |
|
if ((dl = dlinkFindDelete(&listing_client_list, source_p)) != NULL) |
| 709 |
|
free_dlink_node(dl); |
| 735 |
|
* side effects - |
| 736 |
|
*/ |
| 737 |
|
static int |
| 738 |
< |
list_allow_channel(const char *chname, struct ListTask *lt) |
| 738 |
> |
list_allow_channel(const char *chname, const struct ListTask *lt) |
| 739 |
|
{ |
| 740 |
< |
dlink_node *dl = NULL; |
| 740 |
> |
const dlink_node *dl = NULL; |
| 741 |
|
|
| 742 |
|
DLINK_FOREACH(dl, lt->show_mask.head) |
| 743 |
< |
if (!match_chan(dl->data, chname)) |
| 743 |
> |
if (match(dl->data, chname) != 0) |
| 744 |
|
return 0; |
| 745 |
|
|
| 746 |
|
DLINK_FOREACH(dl, lt->hide_mask.head) |
| 747 |
< |
if (match_chan(dl->data, chname)) |
| 747 |
> |
if (match(dl->data, chname) == 0) |
| 748 |
|
return 0; |
| 749 |
|
|
| 750 |
|
return 1; |
| 762 |
|
list_one_channel(struct Client *source_p, struct Channel *chptr, |
| 763 |
|
struct ListTask *list_task) |
| 764 |
|
{ |
| 765 |
< |
if (SecretChannel(chptr) && !IsMember(source_p, chptr)) |
| 765 |
> |
if (SecretChannel(chptr) && |
| 766 |
> |
!(IsMember(source_p, chptr) || HasUMode(source_p, UMODE_ADMIN))) |
| 767 |
|
return; |
| 768 |
|
if (dlink_list_length(&chptr->members) < list_task->users_min || |
| 769 |
|
dlink_list_length(&chptr->members) > list_task->users_max || |