Ejemplo n.º 1
0
/** Associate a specific configuration entry to a *local* client (this
 * is the one which used in accepting the connection). Note, that this
 * automatically changes the attachment if there was an old one...
 * @param cptr Client to attach \a aconf to
 * @param aconf ConfItem to attach
 * @return Authorization check result.
 */
enum AuthorizationCheckResult attach_conf(struct Client *cptr, struct ConfItem *aconf)
{
  struct SLink *lp;

  if (is_attached(aconf, cptr))
    return ACR_ALREADY_AUTHORIZED;
  if (IsIllegal(aconf))
    return ACR_NO_AUTHORIZATION;
  if ((aconf->status & (CONF_OPERATOR | CONF_CLIENT)) &&
      ConfLinks(aconf) >= ConfMaxLinks(aconf) && ConfMaxLinks(aconf) > 0)
    return ACR_TOO_MANY_IN_CLASS;  /* Use this for printing error message */
  lp = make_link();
  lp->next = cli_confs(cptr);
  lp->value.aconf = aconf;
  cli_confs(cptr) = lp;
  ++aconf->clients;
  if (aconf->status & CONF_CLIENT_MASK)
    ConfLinks(aconf)++;
  return ACR_OK;
}
Ejemplo n.º 2
0
/** Look for any connections that we should try to initiate.
 * Reschedules itself to run again at the appropriate time.
 * @param[in] ev Timer event (ignored).
 */
static void try_connections(struct Event* ev) {
  struct ConfItem*  aconf;
  struct ConfItem** pconf;
  time_t            next;
  struct Jupe*      ajupe;
  int               hold;
  int               done;

  assert(ET_EXPIRE == ev_type(ev));
  assert(0 != ev_timer(ev));

  Debug((DEBUG_NOTICE, "Connection check at   : %s", myctime(CurrentTime)));
  next = CurrentTime + feature_int(FEAT_CONNECTFREQUENCY);
  done = 0;

  for (aconf = GlobalConfList; aconf; aconf = aconf->next) {
    /* Only consider server items with non-zero port and non-zero
     * connect times that are not actively juped.
     */
    if (!(aconf->status & CONF_SERVER)
        || aconf->address.port == 0
        || !(aconf->flags & CONF_AUTOCONNECT)
        || ((ajupe = jupe_find(aconf->name)) && JupeIsActive(ajupe)))
      continue;

    /* Do we need to postpone this connection further? */
    hold = aconf->hold > CurrentTime;

    /* Update next possible connection check time. */
    if (hold && next > aconf->hold)
        next = aconf->hold;

    /* Do not try to connect if its use is still on hold until future,
     * we have already initiated a connection this try_connections(),
     * too many links in its connection class, it is already linked,
     * or if connect rules forbid a link now.
     */
    if (hold || done
        || (ConfLinks(aconf) > ConfMaxLinks(aconf))
        || FindServer(aconf->name)
        || conf_eval_crule(aconf->name, CRULE_MASK))
      continue;

    /* Ensure it is at the end of the list for future checks. */
    if (aconf->next) {
      /* Find aconf's location in the list and splice it out. */
      for (pconf = &GlobalConfList; *pconf; pconf = &(*pconf)->next)
        if (*pconf == aconf)
          *pconf = aconf->next;
      /* Reinsert it at the end of the list (where pconf is now). */
      *pconf = aconf;
      aconf->next = 0;
    }

    /* Activate the connection itself. */
    if (connect_server(aconf, 0))
      sendto_opmask_butone(0, SNO_OLDSNO, "Connection to %s activated.",
			   aconf->name);

    /* And stop looking for further candidates. */
    done = 1;
  }

  Debug((DEBUG_NOTICE, "Next connection check : %s", myctime(next)));
  timer_add(&connect_timer, try_connections, 0, TT_ABSOLUTE, next);
}