コード例 #1
0
ファイル: class.c プロジェクト: jast/ircu-now
/** Get connection class name for a configuration item.
 * @param[in] aconf Configuration item to check.
 * @return Name of connection class associated with \a aconf.
 */
char*
get_conf_class(const struct ConfItem* aconf)
{
  if ((aconf) && (aconf->conn_class))
    return (ConfClass(aconf));

  Debug((DEBUG_DEBUG, "No Class For %s", (aconf) ? aconf->name : "*No Conf*"));

  return NULL;
}
コード例 #2
0
ファイル: ircd.c プロジェクト: DanielOaks/irc2-mirror
/*
** try_connections
**
**	Scan through configuration and try new connections.
**	Returns the calendar time when the next call to this
**	function should be made latest. (No harm done if this
**	is called earlier or later...)
*/
static	time_t	try_connections(time_t currenttime)
{
	Reg	aConfItem *aconf;
	Reg	aClient *cptr;
	aConfItem **pconf;
	int	confrq;
	time_t	next = 0;
	aClass	*cltmp;
	aConfItem *con_conf = NULL;
	int	allheld = 1;
#ifdef DISABLE_DOUBLE_CONNECTS
	int	i;
#endif

	if ((bootopt & BOOT_STANDALONE))
		return 0;

	Debug((DEBUG_NOTICE,"Connection check at   : %s",
		myctime(currenttime)));
	for (aconf = conf; aconf; aconf = aconf->next )
	{
		/* not a C-line */
		if (!(aconf->status & (CONF_CONNECT_SERVER|CONF_ZCONNECT_SERVER)))
			continue;

		/* not a candidate for AC */
		if (aconf->port <= 0)
			continue;

		cltmp = Class(aconf);
		/* not a candidate for AC */
		if (MaxLinks(cltmp) == 0)
			continue;

		/* minimize next to lowest hold time of all AC-able C-lines */
		if (next > aconf->hold || next == 0)
			next = aconf->hold;

		/* skip conf if the use of it is on hold until future. */
		if (aconf->hold > currenttime)
			continue;

		/* at least one candidate not held for future, good */
		allheld = 0;

		/* see if another link in this conf is allowed */
		if (Links(cltmp) >= MaxLinks(cltmp))
			continue;
		
		/* next possible check after connfreq secs for this C-line */
		confrq = get_con_freq(cltmp);
		aconf->hold = currenttime + confrq;

		/* is this server already connected? */
		cptr = find_name(aconf->name, (aClient *)NULL);
		if (!cptr)
			cptr = find_mask(aconf->name, (aClient *)NULL);

		/* matching client already exists, no AC to it */
		if (cptr)
			continue;

		/* no such server, check D-lines */
		if (find_denied(aconf->name, Class(cltmp)))
			continue;

#ifdef DISABLE_DOUBLE_CONNECTS
		/* Much better would be traversing only unknown
		** connections, but this requires another global
		** variable, adding and removing from there in
		** proper places etc. Some day. --B. */
		for (i = highest_fd; i >= 0; i--)
		{
			if (!(cptr = local[i]) ||
				cptr->status > STAT_UNKNOWN)
			{
				continue;
			}
			/* an unknown traveller we have */
			if (
#ifndef INET6
				cptr->ip.s_addr == aconf->ipnum.s_addr
#else
				!memcmp(cptr->ip.s6_addr,
					aconf->ipnum.s6_addr, 16)
#endif
			)
			{
				/* IP the same. Coincidence? Maybe.
				** Do not cause havoc with double connect. */
				break;
			}
			cptr = NULL;
		}
		if (cptr)
		{
			sendto_flag(SCH_SERVER, "AC to %s postponed", aconf->name);
			continue;
		}
#endif
		/* we have a candidate! */

		/* choose the best. */
		if (!con_conf ||
		     (con_conf->pref > aconf->pref && aconf->pref >= 0) ||
		     (con_conf->pref == -1 &&
		      Class(cltmp) > ConfClass(con_conf)))
		{
			con_conf = aconf;
		}
		/* above is my doubt: if we always choose best connection
		** and it always fails connecting, we may never try another,
		** even "worse"; what shall we do? --Beeth */
	}
	if (con_conf)
	{
		if (con_conf->next)  /* are we already last? */
		{
			for (pconf = &conf; (aconf = *pconf);
			     pconf = &(aconf->next))
				/* put the current one at the end and
				 * make sure we try all connections
				 */
				if (aconf == con_conf)
					*pconf = aconf->next;
			(*pconf = con_conf)->next = 0;
		}

		/* "Penalty" for being the best, so in next call of
		 * try_connections() other servers have chance. --B. */
		con_conf->hold += get_con_freq(Class(con_conf));

		if (!iconf.aconnect)
		{
			sendto_flag(SCH_NOTICE,
				"Connection to %s deferred. Autoconnect "
				"administratively disabled", con_conf->name);
		}
		else if (connect_server(con_conf, (aClient *)NULL,
				   (struct hostent *)NULL) == 0)
		{
			sendto_flag(SCH_NOTICE,
				    "Connection to %s[%s] activated.",
				    con_conf->name, con_conf->host);
		}
	}
	else
	if (allheld == 0)	/* disable AC only when some C: got checked */
	{
		/* No suitable conf for AC was found, so why bother checking
		** again? If some server quits, it'd get reenabled --B. */
		next = 0;
	}
	Debug((DEBUG_NOTICE,"Next connection check : %s", myctime(next)));
	return (next);
}
コード例 #3
0
ファイル: s_conf.c プロジェクト: kisserlb/enet-1.0
/** Interpret \a client as a client specifier and show which Client
 * block(s) match that client.
 *
 * The client specifier may contain an IP address, hostname, listener
 * port, or a combination of those separated by commas.  IP addresses
 * and hostnamese may be preceded by "username@"; the last given
 * username will be used for the match.
 *
 * @param[in] client Client specifier.
 * @return Matching Client block structure.
 */
struct ConfItem *conf_debug_iline(const char *client)
{
  struct irc_in_addr address;
  struct ConfItem *aconf;
  struct DenyConf *deny;
  char *sep;
  unsigned short listener;
  char username[USERLEN+1], hostname[HOSTLEN+1], realname[REALLEN+1];

  /* Initialize variables. */
  listener = 0;
  memset(&address, 0, sizeof(address));
  memset(&username, 0, sizeof(username));
  memset(&hostname, 0, sizeof(hostname));
  memset(&realname, 0, sizeof(realname));

  /* Parse client specifier. */
  while (*client) {
    struct irc_in_addr tmpaddr;
    long tmp;

    /* Try to parse as listener port number first. */
    tmp = strtol(client, &sep, 10);
    if (tmp && (*sep == '\0' || *sep == ',')) {
      listener = tmp;
      client = sep + (*sep != '\0');
      continue;
    }

    /* Maybe username@ before an IP address or hostname? */
    tmp = strcspn(client, ",@");
    if (client[tmp] == '@') {
      if (tmp > USERLEN)
        tmp = USERLEN;
      ircd_strncpy(username, client, tmp);
      /* and fall through */
      client += tmp + 1;
    }

    /* Looks like an IP address? */
    tmp = ircd_aton(&tmpaddr, client);
    if (tmp && (client[tmp] == '\0' || client[tmp] == ',')) {
        memcpy(&address, &tmpaddr, sizeof(address));
        client += tmp + (client[tmp] != '\0');
        continue;
    }

    /* Realname? */
    if (client[0] == '$' && client[1] == 'R') {
      client += 2;
      for (tmp = 0; *client != '\0' && *client != ',' && tmp < REALLEN; ++client, ++tmp) {
        if (*client == '\\')
          realname[tmp] = *++client;
        else
          realname[tmp] = *client;
      }
      continue;
    }

    /* Else must be a hostname. */
    tmp = strcspn(client, ",");
    if (tmp > HOSTLEN)
      tmp = HOSTLEN;
    ircd_strncpy(hostname, client, tmp);
    client += tmp + (client[tmp] != '\0');
  }

  /* Walk configuration to find matching Client block. */
  for (aconf = GlobalConfList; aconf; aconf = aconf->next) {
    if (aconf->status != CONF_CLIENT)
      continue;
    if (aconf->address.port && aconf->address.port != listener) {
      fprintf(stdout, "Listener port mismatch: %u != %u\n", aconf->address.port, listener);
      continue;
    }
    if (aconf->username && match(aconf->username, username)) {
      fprintf(stdout, "Username mismatch: %s != %s\n", aconf->username, username);
      continue;
    }
    if (aconf->host && match(aconf->host, hostname)) {
      fprintf(stdout, "Hostname mismatch: %s != %s\n", aconf->host, hostname);
      continue;
    }
    if ((aconf->addrbits >= 0)
        && !ipmask_check(&address, &aconf->address.addr, aconf->addrbits)) {
      fprintf(stdout, "IP address mismatch: %s != %s\n", aconf->name, ircd_ntoa(&address));
      continue;
    }
    fprintf(stdout, "Match! username=%s host=%s ip=%s class=%s maxlinks=%u password=%s\n",
            (aconf->username ? aconf->username : "******"),
            (aconf->host ? aconf->host : "(null)"),
            (aconf->name ? aconf->name : "(null)"),
            ConfClass(aconf), aconf->maximum,
            (aconf->passwd ? aconf->passwd : "(null)"));
    break;
  }

  /* If no authorization, say so and exit. */
  if (!aconf)
  {
    fprintf(stdout, "No authorization found.\n");
    return NULL;
  }

  /* Look for a Kill block with the user's name on it. */
  for (deny = denyConfList; deny; deny = deny->next) {
    if (deny->usermask && match(deny->usermask, username))
      continue;
    if (deny->realmask && match(deny->realmask, realname))
      continue;
    if (deny->bits > 0) {
      if (!ipmask_check(&address, &deny->address, deny->bits))
        continue;
    } else if (deny->hostmask && match(deny->hostmask, hostname))
      continue;

    /* Looks like a match; report it. */
    fprintf(stdout, "Denied! usermask=%s realmask=\"%s\" hostmask=%s (bits=%u)\n",
            deny->usermask ? deny->usermask : "(null)",
            deny->realmask ? deny->realmask : "(null)",
            deny->hostmask ? deny->hostmask : "(null)",
            deny->bits);
  }

  return aconf;
}