ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf.c
(Generate patch)

Comparing ircd-hybrid/trunk/src/conf.c (file contents):
Revision 3860 by michael, Thu Jun 5 19:55:07 2014 UTC vs.
Revision 4321 by michael, Fri Aug 1 16:55:07 2014 UTC

# Line 56 | Line 56
56   #include "motd.h"
57  
58  
59 struct config_channel_entry ConfigChannel;
60 struct config_server_hide ConfigServerHide;
61 struct config_file_entry ConfigFileEntry;
62 struct logging_entry ConfigLoggingEntry = { .use_logging = 1 };
63 struct server_info ServerInfo;
64 struct admin_info AdminInfo;
65
59   /* general conf items link list root, other than k lines etc. */
60   dlink_list service_items = { NULL, NULL, 0 };
61   dlink_list server_items  = { NULL, NULL, 0 };
# Line 71 | Line 64 | dlink_list oconf_items   = { NULL, NULL,
64   dlink_list uconf_items   = { NULL, NULL, 0 };
65   dlink_list xconf_items   = { NULL, NULL, 0 };
66   dlink_list nresv_items   = { NULL, NULL, 0 };
67 < dlink_list cresv_items = { NULL, NULL, 0 };
67 > dlink_list cresv_items   = { NULL, NULL, 0 };
68  
69   extern unsigned int lineno;
70   extern char linebuf[];
71   extern char conffilebuf[IRCD_BUFSIZE];
72   extern int yyparse(); /* defined in y.tab.c */
73  
81 struct conf_parser_context conf_parser_ctx = { 0, 0, NULL };
82
74   /* internally defined functions */
75   static void read_conf(FILE *);
76   static void clear_out_old_conf(void);
77   static void expire_tklines(dlink_list *);
78 < static void garbage_collect_ip_entries(void);
79 < static int hash_ip(struct irc_ssaddr *);
78 > static void ipcache_remove_expired_entries(void *);
79 > static uint32_t hash_ip(const struct irc_ssaddr *);
80   static int verify_access(struct Client *);
81   static int attach_iline(struct Client *, struct MaskItem *);
82   static struct ip_entry *find_or_add_ip(struct irc_ssaddr *);
# Line 101 | Line 92 | static int find_user_host(struct Client
92  
93   struct ip_entry
94   {
95 +  dlink_node node;                /**< Doubly linked list node. */
96    struct irc_ssaddr ip;
97 <  unsigned int count;
98 <  time_t last_attempt;
99 <  struct ip_entry *next;
97 >  unsigned int count;             /**< Number of registered users using this IP */
98 >  unsigned int connection_count;  /**< Number of connections from this IP in the last throttle_time duration */
99 >  time_t last_attempt;            /**< The last time someone connected from this IP */
100   };
101  
102 < static struct ip_entry *ip_hash_table[IP_HASH_SIZE];
102 > static dlink_list ip_hash_table[IP_HASH_SIZE];
103   static mp_pool_t *ip_entry_pool = NULL;
112 static int ip_entries_count = 0;
104  
105  
106   /* conf_dns_callback()
# Line 435 | Line 426 | attach_iline(struct Client *client_p, st
426   *                      - clear the ip hash table
427   */
428   void
429 < init_ip_hash_table(void)
429 > ipcache_init(void)
430   {
431 +  static struct event event_expire_ipcache =
432 +  {
433 +    .name = "ipcache_remove_expired_entries",
434 +    .handler = ipcache_remove_expired_entries,
435 +    .when = 123
436 +  };
437 +
438 +  event_add(&event_expire_ipcache, NULL);
439    ip_entry_pool = mp_pool_new(sizeof(struct ip_entry), MP_CHUNK_SIZE_IP_ENTRY);
441  memset(ip_hash_table, 0, sizeof(ip_hash_table));
440   }
441  
442   /* find_or_add_ip()
# Line 451 | Line 449 | init_ip_hash_table(void)
449   * count set to 0.
450   */
451   static struct ip_entry *
452 < find_or_add_ip(struct irc_ssaddr *ip_in)
452 > find_or_add_ip(struct irc_ssaddr *addr)
453   {
454 <  struct ip_entry *ptr, *newptr;
455 <  int hash_index = hash_ip(ip_in), res;
456 <  struct sockaddr_in *v4 = (struct sockaddr_in *)ip_in, *ptr_v4;
454 >  dlink_node *ptr = NULL;
455 >  struct ip_entry *iptr = NULL;
456 >  uint32_t hash_index = hash_ip(addr);
457 >  int res = 0;
458 >  struct sockaddr_in *v4 = (struct sockaddr_in *)addr, *ptr_v4;
459   #ifdef IPV6
460 <  struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)ip_in, *ptr_v6;
460 >  struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr, *ptr_v6;
461   #endif
462  
463 <  for (ptr = ip_hash_table[hash_index]; ptr; ptr = ptr->next)
463 >  DLINK_FOREACH(ptr, ip_hash_table[hash_index].head)
464    {
465 +    iptr = ptr->data;
466   #ifdef IPV6
467 <    if (ptr->ip.ss.ss_family != ip_in->ss.ss_family)
467 >    if (iptr->ip.ss.ss_family != addr->ss.ss_family)
468        continue;
469 <    if (ip_in->ss.ss_family == AF_INET6)
469 >
470 >    if (addr->ss.ss_family == AF_INET6)
471      {
472 <      ptr_v6 = (struct sockaddr_in6 *)&ptr->ip;
472 >      ptr_v6 = (struct sockaddr_in6 *)&iptr->ip;
473        res = memcmp(&v6->sin6_addr, &ptr_v6->sin6_addr, sizeof(struct in6_addr));
474      }
475      else
476   #endif
477      {
478 <      ptr_v4 = (struct sockaddr_in *)&ptr->ip;
478 >      ptr_v4 = (struct sockaddr_in *)&iptr->ip;
479        res = memcmp(&v4->sin_addr, &ptr_v4->sin_addr, sizeof(struct in_addr));
480      }
481 +
482      if (res == 0)
483 <    {
481 <      /* Found entry already in hash, return it. */
482 <      return ptr;
483 <    }
483 >      return iptr;  /* Found entry already in hash, return it. */
484    }
485  
486 <  if (ip_entries_count >= 2 * hard_fdlimit)
487 <    garbage_collect_ip_entries();
486 >  iptr = mp_pool_get(ip_entry_pool);
487 >  memcpy(&iptr->ip, addr, sizeof(struct irc_ssaddr));
488  
489 <  newptr = mp_pool_get(ip_entry_pool);
490 <  memset(newptr, 0, sizeof(*newptr));
491 <  ip_entries_count++;
492 <  memcpy(&newptr->ip, ip_in, sizeof(struct irc_ssaddr));
489 >  dlinkAdd(iptr, &iptr->node, &atable[hash_index]);
490  
491 <  newptr->next = ip_hash_table[hash_index];
495 <  ip_hash_table[hash_index] = newptr;
496 <
497 <  return newptr;
491 >  return iptr;
492   }
493  
494   /* remove_one_ip()
# Line 507 | Line 501 | find_or_add_ip(struct irc_ssaddr *ip_in)
501   *                 the struct ip_entry is returned to the ip_entry_heap
502   */
503   void
504 < remove_one_ip(struct irc_ssaddr *ip_in)
504 > remove_one_ip(struct irc_ssaddr *addr)
505   {
506 <  struct ip_entry *ptr;
507 <  struct ip_entry *last_ptr = NULL;
508 <  int hash_index = hash_ip(ip_in), res;
509 <  struct sockaddr_in *v4 = (struct sockaddr_in *)ip_in, *ptr_v4;
506 >  dlink_node *ptr = NULL;
507 >  uint32_t hash_index = hash_ip(addr);
508 >  int res = 0;
509 >  struct sockaddr_in *v4 = (struct sockaddr_in *)addr, *ptr_v4;
510   #ifdef IPV6
511 <  struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)ip_in, *ptr_v6;
511 >  struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr, *ptr_v6;
512   #endif
513  
514 <  for (ptr = ip_hash_table[hash_index]; ptr; ptr = ptr->next)
514 >  DLINK_FOREACH(ptr, ip_hash_table[hash_index].head)
515    {
516 +    struct ip_entry *iptr = ptr->data;
517   #ifdef IPV6
518 <    if (ptr->ip.ss.ss_family != ip_in->ss.ss_family)
518 >    if (iptr->ip.ss.ss_family != addr->ss.ss_family)
519        continue;
520 <    if (ip_in->ss.ss_family == AF_INET6)
520 >    if (addr->ss.ss_family == AF_INET6)
521      {
522 <      ptr_v6 = (struct sockaddr_in6 *)&ptr->ip;
522 >      ptr_v6 = (struct sockaddr_in6 *)&iptr->ip;
523        res = memcmp(&v6->sin6_addr, &ptr_v6->sin6_addr, sizeof(struct in6_addr));
524      }
525      else
526   #endif
527      {
528 <      ptr_v4 = (struct sockaddr_in *)&ptr->ip;
528 >      ptr_v4 = (struct sockaddr_in *)&iptr->ip;
529        res = memcmp(&v4->sin_addr, &ptr_v4->sin_addr, sizeof(struct in_addr));
530      }
531 +
532      if (res)
533        continue;
534 <    if (ptr->count > 0)
539 <      ptr->count--;
540 <    if (ptr->count == 0 &&
541 <        (CurrentTime-ptr->last_attempt) >= ConfigFileEntry.throttle_time)
542 <    {
543 <      if (last_ptr != NULL)
544 <        last_ptr->next = ptr->next;
545 <      else
546 <        ip_hash_table[hash_index] = ptr->next;
534 >    assert(iptr->count > 0);
535  
536 <      mp_pool_release(ptr);
537 <      ip_entries_count--;
536 >    if (--iptr->count == 0 &&
537 >        (CurrentTime - iptr->last_attempt) >= ConfigFileEntry.throttle_time)
538 >    {
539 >      dlinkDelete(&iptr->node, &ip_hash_table[hash_index]);
540 >      mp_pool_release(iptr);
541        return;
542      }
552    last_ptr = ptr;
543    }
544   }
545  
# Line 559 | Line 549 | remove_one_ip(struct irc_ssaddr *ip_in)
549   * output       - integer value used as index into hash table
550   * side effects - hopefully, none
551   */
552 < static int
553 < hash_ip(struct irc_ssaddr *addr)
552 > static uint32_t
553 > hash_ip(const struct irc_ssaddr *addr)
554   {
555    if (addr->ss.ss_family == AF_INET)
556    {
557 <    struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
558 <    int hash;
569 <    uint32_t ip;
557 >    const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
558 >    uint32_t hash = 0, ip = ntohl(v4->sin_addr.s_addr);
559  
560 <    ip   = ntohl(v4->sin_addr.s_addr);
572 <    hash = ((ip >> 12) + ip) & (IP_HASH_SIZE-1);
560 >    hash = ((ip >> 12) + ip) & (IP_HASH_SIZE - 1);
561      return hash;
562    }
563   #ifdef IPV6
564    else
565    {
566 <    int hash;
567 <    struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
580 <    uint32_t *ip = (uint32_t *)&v6->sin6_addr.s6_addr;
566 >    const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
567 >    uint32_t hash = 0, *ip = (uint32_t *)&v6->sin6_addr.s6_addr;
568  
569      hash  = ip[0] ^ ip[3];
570      hash ^= hash >> 16;
# Line 603 | Line 590 | hash_ip(struct irc_ssaddr *addr)
590   void
591   count_ip_hash(unsigned int *number_ips_stored, uint64_t *mem_ips_stored)
592   {
606  struct ip_entry *ptr;
607
593    *number_ips_stored = 0;
594    *mem_ips_stored    = 0;
595  
596    for (unsigned int i = 0; i < IP_HASH_SIZE; ++i)
597    {
598 <    for (ptr = ip_hash_table[i]; ptr; ptr = ptr->next)
599 <    {
615 <      *number_ips_stored += 1;
616 <      *mem_ips_stored += sizeof(struct ip_entry);
617 <    }
598 >    *number_ips_stored += dlink_list_length(&ip_hash_table[i]);
599 >    *mem_ips_stored += dlink_list_length(&ip_hash_table[i]) * sizeof(struct ip_entry);
600    }
601   }
602  
# Line 625 | Line 607 | count_ip_hash(unsigned int *number_ips_s
607   * side effects - free up all ip entries with no connections
608   */
609   static void
610 < garbage_collect_ip_entries(void)
610 > ipcache_remove_expired_entries(void *unused)
611   {
612 <  struct ip_entry *ptr;
631 <  struct ip_entry *last_ptr;
632 <  struct ip_entry *next_ptr;
612 >  dlink_node *ptr = NULL, *ptr_next = NULL;
613  
614    for (unsigned int i = 0; i < IP_HASH_SIZE; ++i)
615    {
616 <    last_ptr = NULL;
637 <
638 <    for (ptr = ip_hash_table[i]; ptr; ptr = next_ptr)
616 >    DLINK_FOREACH_SAFE(ptr, ptr_next, ip_hash_table[i].head)
617      {
618 <      next_ptr = ptr->next;
618 >      struct ip_entry *iptr = ptr->data;
619  
620 <      if (ptr->count == 0 &&
621 <          (CurrentTime - ptr->last_attempt) >= ConfigFileEntry.throttle_time)
620 >      if (iptr->count == 0 &&
621 >          (CurrentTime - iptr->last_attempt) >= ConfigFileEntry.throttle_time)
622        {
623 <        if (last_ptr != NULL)
624 <          last_ptr->next = ptr->next;
647 <        else
648 <          ip_hash_table[i] = ptr->next;
649 <        mp_pool_release(ptr);
650 <        ip_entries_count--;
623 >        dlinkDelete(&iptr->node, &ip_hash_table[i]);
624 >        mp_pool_release(iptr);
625        }
652      else
653        last_ptr = ptr;
626      }
627    }
628   }
# Line 1046 | Line 1018 | rehash(int sig)
1018      strlcpy(me.info, ServerInfo.description, sizeof(me.info));
1019  
1020    load_conf_modules();
1021 <
1050 <  rehashed_klines = 1;
1021 >  check_conf_klines();
1022  
1023    return 0;
1024   }
# Line 1070 | Line 1041 | set_default_conf(void)
1041    assert(class_default == class_get_list()->tail->data);
1042  
1043   #ifdef HAVE_LIBCRYPTO
1044 +  ServerInfo.message_digest_algorithm = EVP_sha256();
1045    ServerInfo.rsa_private_key = NULL;
1046    ServerInfo.rsa_private_key_file = NULL;
1047   #endif
# Line 1088 | Line 1060 | set_default_conf(void)
1060    ServerInfo.max_clients = MAXCLIENTS_MAX;
1061    ServerInfo.max_nick_length = 9;
1062    ServerInfo.max_topic_length = 80;
1091
1063    ServerInfo.hub = 0;
1064    ServerInfo.dns_host.sin_addr.s_addr = 0;
1065    ServerInfo.dns_host.sin_port = 0;
1066 +
1067    AdminInfo.name = NULL;
1068    AdminInfo.email = NULL;
1069    AdminInfo.description = NULL;
# Line 1106 | Line 1078 | set_default_conf(void)
1078    ConfigChannel.knock_client_count = 1;
1079    ConfigChannel.knock_client_time = 300;
1080    ConfigChannel.knock_delay_channel = 60;
1081 <  ConfigChannel.max_chans_per_user = 25;
1110 <  ConfigChannel.max_chans_per_oper = 50;
1081 >  ConfigChannel.max_channels = 25;
1082    ConfigChannel.max_bans = 25;
1083    ConfigChannel.default_split_user_count = 0;
1084    ConfigChannel.default_split_server_count = 0;
# Line 1123 | Line 1094 | set_default_conf(void)
1094    ConfigServerHide.hide_server_ips = 0;
1095    ConfigServerHide.disable_remote_commands = 0;
1096  
1097 +  ConfigFileEntry.away_count = 2;
1098 +  ConfigFileEntry.away_time = 10;
1099    ConfigFileEntry.service_name = xstrdup(SERVICE_NAME_DEFAULT);
1100    ConfigFileEntry.max_watch = WATCHSIZE_DEFAULT;
1101    ConfigFileEntry.cycle_on_host_change = 1;
# Line 1167 | Line 1140 | set_default_conf(void)
1140    ConfigFileEntry.oper_pass_resv = 1;
1141    ConfigFileEntry.max_targets = MAX_TARGETS_DEFAULT;
1142    ConfigFileEntry.oper_only_umodes = UMODE_DEBUG;
1143 <  ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE |
1144 <    UMODE_OPERWALL | UMODE_WALLOP;
1145 <  ConfigFileEntry.use_egd = 0;
1173 <  ConfigFileEntry.egdpool_path = NULL;
1174 <  ConfigFileEntry.throttle_time = 10;
1143 >  ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE | UMODE_WALLOP;
1144 >  ConfigFileEntry.throttle_count = 1;
1145 >  ConfigFileEntry.throttle_time = 1;
1146   }
1147  
1148   static void
# Line 1266 | Line 1237 | lookup_confhost(struct MaskItem *conf)
1237   int
1238   conf_connect_allowed(struct irc_ssaddr *addr, int aftype)
1239   {
1240 <  struct ip_entry *ip_found;
1240 >  struct ip_entry *ip_found = NULL;
1241    struct MaskItem *conf = find_dline_conf(addr, aftype);
1242  
1243    /* DLINE exempt also gets you out of static limits/pacing... */
# Line 1278 | Line 1249 | conf_connect_allowed(struct irc_ssaddr *
1249  
1250    ip_found = find_or_add_ip(addr);
1251  
1252 <  if ((CurrentTime - ip_found->last_attempt) <
1282 <      ConfigFileEntry.throttle_time)
1252 >  if ((CurrentTime - ip_found->last_attempt) < ConfigFileEntry.throttle_time)
1253    {
1254 <    ip_found->last_attempt = CurrentTime;
1255 <    return TOO_FAST;
1254 >    if (ip_found->connection_count >= ConfigFileEntry.throttle_count)
1255 >      return TOO_FAST;
1256 >
1257 >    ++ip_found->connection_count;
1258    }
1259 +  else
1260 +    ip_found->connection_count = 1;
1261  
1262    ip_found->last_attempt = CurrentTime;
1263    return 0;
# Line 1357 | Line 1331 | static const struct oper_privs
1331    { OPER_FLAG_DIE,            'D' },
1332    { OPER_FLAG_GLINE,          'G' },
1333    { OPER_FLAG_REHASH,         'H' },
1334 <  { OPER_FLAG_K,              'K' },
1361 <  { OPER_FLAG_OPERWALL,       'L' },
1334 >  { OPER_FLAG_KLINE,          'K' },
1335    { OPER_FLAG_KILL,           'N' },
1336    { OPER_FLAG_KILL_REMOTE,    'O' },
1337    { OPER_FLAG_CONNECT,        'P' },
# Line 1390 | Line 1363 | oper_privs_as_string(const unsigned int
1363   }
1364  
1365   /*
1366 < * Input: A client to find the active oper{} name for.
1366 > * Input: A client to find the active operator {} name for.
1367   * Output: The nick!user@host{oper} of the oper.
1368   *         "oper" is server name for remote opers
1369   * Side effects: None.
# Line 1416 | Line 1389 | get_oper_name(const struct Client *clien
1389        }
1390      }
1391  
1392 <    /* Probably should assert here for now. If there is an oper out there
1393 <     * with no oper{} conf attached, it would be good for us to know...
1392 >    /*
1393 >     * Probably should assert here for now. If there is an oper out there
1394 >     * with no operator {} conf attached, it would be good for us to know...
1395       */
1396 <    assert(0); /* Oper without oper conf! */
1396 >    assert(0);  /* Oper without oper conf! */
1397    }
1398  
1399    snprintf(buffer, sizeof(buffer), "%s!%s@%s{%s}", client_p->name,
# Line 1445 | Line 1419 | read_conf_files(int cold)
1419  
1420    /* We need to know the initial filename for the yyerror() to report
1421       FIXME: The full path is in conffilenamebuf first time since we
1422 <             dont know anything else
1422 >             don't know anything else
1423  
1424       - Gozem 2002-07-21
1425    */
# Line 1485 | Line 1459 | read_conf_files(int cold)
1459    add_isupport("CHANTYPES", "#", -1);
1460  
1461    snprintf(chanlimit, sizeof(chanlimit), "#:%d",
1462 <           ConfigChannel.max_chans_per_user);
1462 >           ConfigChannel.max_channels);
1463    add_isupport("CHANLIMIT", chanlimit, -1);
1464 <  snprintf(chanmodes, sizeof(chanmodes), "%s", "beI,k,l,imnprstORS");
1464 >  snprintf(chanmodes, sizeof(chanmodes), "%s", "beI,k,l,cimnprstMORS");
1465    add_isupport("CHANNELLEN", NULL, CHANNELLEN);
1466    add_isupport("TOPICLEN", NULL, ServerInfo.max_topic_length);
1467    add_isupport("CHANMODES", chanmodes, -1);
# Line 1566 | Line 1540 | clear_out_old_conf(void)
1540    ServerInfo.network_name = NULL;
1541    MyFree(ServerInfo.network_desc);
1542    ServerInfo.network_desc = NULL;
1569  MyFree(ConfigFileEntry.egdpool_path);
1570  ConfigFileEntry.egdpool_path = NULL;
1543   #ifdef HAVE_LIBCRYPTO
1544    if (ServerInfo.rsa_private_key)
1545    {
# Line 1577 | Line 1549 | clear_out_old_conf(void)
1549  
1550    MyFree(ServerInfo.rsa_private_key_file);
1551    ServerInfo.rsa_private_key_file = NULL;
1580
1581  if (ServerInfo.server_ctx)
1582    SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv2|
1583                                               SSL_OP_NO_SSLv3|
1584                                               SSL_OP_NO_TLSv1);
1585  if (ServerInfo.client_ctx)
1586    SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv2|
1587                                               SSL_OP_NO_SSLv3|
1588                                               SSL_OP_NO_TLSv1);
1552   #endif
1553  
1554    /* clean out AdminInfo */
# Line 1738 | Line 1701 | valid_wild_card_simple(const char *data)
1701   {
1702    const unsigned char *p = (const unsigned char *)data;
1703    unsigned char tmpch = '\0';
1704 <  int nonwild = 0;
1704 >  unsigned int nonwild = 0;
1705  
1706    while ((tmpch = *p++))
1707    {
1708 <    if (tmpch == '\\')
1708 >    if (tmpch == '\\' && *p)
1709      {
1710        ++p;
1711        if (++nonwild >= ConfigFileEntry.min_nonwildcard_simple)
# Line 1769 | Line 1732 | valid_wild_card_simple(const char *data)
1732   int
1733   valid_wild_card(struct Client *source_p, int warn, int count, ...)
1734   {
1735 <  char tmpch;
1736 <  int nonwild = 0;
1735 >  unsigned char tmpch = '\0';
1736 >  unsigned int nonwild = 0;
1737    va_list args;
1738  
1739    /*
# Line 1789 | Line 1752 | valid_wild_card(struct Client *source_p,
1752  
1753    while (count--)
1754    {
1755 <    const char *p = va_arg(args, const char *);
1755 >    const unsigned char *p = va_arg(args, const unsigned char *);
1756      if (p == NULL)
1757        continue;
1758  
# Line 1812 | Line 1775 | valid_wild_card(struct Client *source_p,
1775  
1776    if (warn)
1777      sendto_one_notice(source_p, &me,
1778 <                      ":Please include at least %d non-wildcard characters with the mask",
1778 >                      ":Please include at least %u non-wildcard characters with the mask",
1779                        ConfigFileEntry.min_nonwildcard);
1780    va_end(args);
1781    return 0;

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)