Example #1
0
/** Report connection classes to a client.
 * @param[in] sptr Client requesting statistics.
 * @param[in] sd Stats descriptor for request (ignored).
 * @param[in] param Extra parameter from user (ignored).
 */
void
report_classes(struct Client *sptr, const struct StatDesc *sd,
               char *param)
{
  struct ConnectionClass *cltmp;

  for (cltmp = connClassList; cltmp; cltmp = cltmp->next)
    send_reply(sptr, RPL_STATSYLINE, (cltmp->valid ? 'Y' : 'y'),
               ConClass(cltmp), PingFreq(cltmp), ConFreq(cltmp),
               MaxLinks(cltmp), MaxSendq(cltmp), Links(cltmp) - 1);
}
Example #2
0
/** Unlink (and dereference) invalid connection classes.
 * This is used in combination with class_mark_delete() during rehash
 * to get rid of connection classes that are no longer in the
 * configuration.
 */
void class_delete_marked(void)
{
  struct ConnectionClass* cl;
  struct ConnectionClass* prev;

  Debug((DEBUG_DEBUG, "Class check:"));

  for (prev = cl = connClassList; cl; cl = prev->next) {
    Debug((DEBUG_DEBUG, "Class %s : CF: %d PF: %d ML: %d LI: %d SQ: %d",
           ConClass(cl), ConFreq(cl), PingFreq(cl), MaxLinks(cl),
           Links(cl), MaxSendq(cl)));
    /*
     * unlink marked classes, delete unreferenced ones
     */
    if (cl->valid || Links(cl) > 1)
      prev = cl;
    else
    {
      prev->next = cl->next;
      free_class(cl);
    }
  }
}
Example #3
0
/** Initialize the connection class list.
 * A connection class named "default" is created, with ping frequency,
 * connection frequency, maximum links and max SendQ values from the
 * corresponding configuration features.
 */
void init_class(void)
{
  if (!connClassList) {
    connClassList = (struct ConnectionClass*) make_class();
    connClassList->next   = 0;
  }

  /* We had better not try and free this... */
  ConClass(connClassList) = "default";
  PingFreq(connClassList) = feature_int(FEAT_PINGFREQUENCY);
  ConFreq(connClassList)  = feature_int(FEAT_CONNECTFREQUENCY);
  MaxLinks(connClassList) = feature_int(FEAT_MAXIMUM_LINKS);
  MaxSendq(connClassList) = feature_uint(FEAT_DEFAULTMAXSENDQLENGTH);
  connClassList->valid    = 1;
  Links(connClassList)    = 1;
}
void UEdGraphSchema_BehaviorTreeDecorator::GetBreakLinkToSubMenuActions( class FMenuBuilder& MenuBuilder, UEdGraphPin* InGraphPin )
{
	// Make sure we have a unique name for every entry in the list
	TMap< FString, uint32 > LinkTitleCount;

	// Add all the links we could break from
	for(TArray<class UEdGraphPin*>::TConstIterator Links(InGraphPin->LinkedTo); Links; ++Links)
	{
		UEdGraphPin* Pin = *Links;
		FString TitleString = Pin->GetOwningNode()->GetNodeTitle(ENodeTitleType::ListView).ToString();
		FText Title = FText::FromString( TitleString );
		if ( Pin->PinName != TEXT("") )
		{
			TitleString = FString::Printf(TEXT("%s (%s)"), *TitleString, *Pin->PinName);

			// Add name of connection if possible
			FFormatNamedArguments Args;
			Args.Add( TEXT("NodeTitle"), Title );
			Args.Add( TEXT("PinName"), Pin->GetDisplayName() );
			Title = FText::Format( LOCTEXT("BreakDescPin", "{NodeTitle} ({PinName})"), Args );
		}

		uint32 &Count = LinkTitleCount.FindOrAdd( TitleString );

		FText Description;
		FFormatNamedArguments Args;
		Args.Add( TEXT("NodeTitle"), Title );
		Args.Add( TEXT("NumberOfNodes"), Count );

		if ( Count == 0 )
		{
			Description = FText::Format( LOCTEXT("BreakDesc", "Break link to {NodeTitle}"), Args );
		}
		else
		{
			Description = FText::Format( LOCTEXT("BreakDescMulti", "Break link to {NodeTitle} ({NumberOfNodes})"), Args );
		}
		++Count;

		MenuBuilder.AddMenuEntry( Description, Description, FSlateIcon(), FUIAction(
			FExecuteAction::CreateUObject((USoundClassGraphSchema*const)this, &USoundClassGraphSchema::BreakSinglePinLink, const_cast< UEdGraphPin* >(InGraphPin), *Links) ) );
	}
}
Example #5
0
/*
** 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);
}
Example #6
0
static
void do_trace(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
    int i;
    struct Client *acptr;
    struct Client *acptr2;
    const struct ConnectionClass* cl;
    char* tname;
    int doall;
    int *link_s;
    int *link_u;
    int cnt = 0;
    int wilds;
    int dow;

    if (parc < 2 || BadPtr(parv[1]))
    {
        /* just "TRACE" without parameters. Must be from local client */
        parc = 1;
        acptr = &me;
        tname = cli_name(&me);
        i = HUNTED_ISME;
    }
    else if (parc < 3 || BadPtr(parv[2]))
    {
        /* No target specified. Make one before propagating. */
        parc = 2;
        tname = parv[1];
        if ((acptr = find_match_server(parv[1])) ||
                ((acptr = FindClient(parv[1])) && !MyUser(acptr)))
        {
            if (IsUser(acptr))
                parv[2] = cli_name(cli_user(acptr)->server);
            else
                parv[2] = cli_name(acptr);
            parc = 3;
            parv[3] = 0;
            if ((i = hunt_server_cmd(sptr, CMD_TRACE, cptr, IsServer(acptr),
                                     "%s :%C", 2, parc, parv)) == HUNTED_NOSUCH)
                return;
        }
        else
            i = HUNTED_ISME;
    } else {
        /* Got "TRACE <tname> :<target>" */
        parc = 3;
        if (MyUser(sptr) || Protocol(cptr) < 10)
            acptr = find_match_server(parv[2]);
        else
            acptr = FindNServer(parv[2]);
        if ((i = hunt_server_cmd(sptr, CMD_TRACE, cptr, 0, "%s :%C", 2, parc,
                                 parv)) == HUNTED_NOSUCH)
            return;
        tname = parv[1];
    }

    if (i == HUNTED_PASS) {
        if (!acptr)
            acptr = next_client(GlobalClientList, tname);
        else
            acptr = cli_from(acptr);
        send_reply(sptr, RPL_TRACELINK,
                   version, debugmode, tname,
                   acptr ? cli_name(cli_from(acptr)) : "<No_match>");
        return;
    }

    doall = (parv[1] && (parc > 1)) ? !match(tname, cli_name(&me)) : 1;
    wilds = !parv[1] || strchr(tname, '*') || strchr(tname, '?');
    dow = wilds || doall;

    /* Don't give (long) remote listings to lusers */
    if (dow && !MyConnect(sptr) && !IsAnOper(sptr)) {
        send_reply(sptr, RPL_TRACEEND);
        return;
    }

    link_s = MyCalloc(2 * maxconnections, sizeof(link_s[0]));
    link_u = link_s + maxconnections;

    if (doall) {
        for (acptr = GlobalClientList; acptr; acptr = cli_next(acptr)) {
            if (IsUser(acptr))
                link_u[cli_fd(cli_from(acptr))]++;
            else if (IsServer(acptr))
                link_s[cli_fd(cli_from(acptr))]++;
        }
    }

    /* report all direct connections */

    for (i = 0; i <= HighestFd; i++) {
        const char *conClass;

        if (!(acptr = LocalClientArray[i])) /* Local Connection? */
            continue;
        if (IsInvisible(acptr) && dow && !(MyConnect(sptr) && IsOper(sptr)) &&
                !IsAnOper(acptr) && (acptr != sptr))
            continue;
        if (!doall && wilds && match(tname, cli_name(acptr)))
            continue;
        if (!dow && 0 != ircd_strcmp(tname, cli_name(acptr)))
            continue;

        conClass = get_client_class(acptr);

        switch (cli_status(acptr)) {
        case STAT_CONNECTING:
            send_reply(sptr, RPL_TRACECONNECTING, conClass, cli_name(acptr));
            cnt++;
            break;
        case STAT_HANDSHAKE:
            send_reply(sptr, RPL_TRACEHANDSHAKE, conClass, cli_name(acptr));
            cnt++;
            break;
        case STAT_ME:
            break;
        case STAT_UNKNOWN:
        case STAT_UNKNOWN_USER:
            send_reply(sptr, RPL_TRACEUNKNOWN, conClass,
                       get_client_name(acptr, HIDE_IP));
            cnt++;
            break;
        case STAT_UNKNOWN_SERVER:
            send_reply(sptr, RPL_TRACEUNKNOWN, conClass, "Unknown Server");
            cnt++;
            break;
        case STAT_USER:
            /* Only opers see users if there is a wildcard
               but anyone can see all the opers. */
            if ((IsAnOper(sptr) && (MyUser(sptr) ||
                                    !(dow && IsInvisible(acptr)))) || !dow || IsAnOper(acptr)) {
                if (IsAnOper(acptr))
                    send_reply(sptr, RPL_TRACEOPERATOR, conClass,
                               get_client_name(acptr, SHOW_IP),
                               CurrentTime - cli_lasttime(acptr));
                else
                    send_reply(sptr, RPL_TRACEUSER, conClass,
                               get_client_name(acptr, SHOW_IP),
                               CurrentTime - cli_lasttime(acptr));
                cnt++;
            }
            break;
        /*
         * Connection is a server
         *
         * Serv <class> <nS> <nC> <name> <ConnBy> <last> <age>
         *
         * class        Class the server is in
         * nS           Number of servers reached via this link
         * nC           Number of clients reached via this link
         * name         Name of the server linked
         * ConnBy       Who established this link
         * last         Seconds since we got something from this link
         * age          Seconds this link has been alive
         *
         * Additional comments etc......        -Cym-<*****@*****.**>
         */

        case STAT_SERVER:
            if (cli_serv(acptr)->user) {
                if (!cli_serv(acptr)->by[0]
                        || !(acptr2 = findNUser(cli_serv(acptr)->by))
                        || (cli_user(acptr2) != cli_serv(acptr)->user))
                    acptr2 = NULL;
                send_reply(sptr, RPL_TRACESERVER, conClass, link_s[i],
                           link_u[i], cli_name(acptr),
                           acptr2 ? cli_name(acptr2) : "*",
                           cli_serv(acptr)->user->username,
                           cli_serv(acptr)->user->host,
                           CurrentTime - cli_lasttime(acptr),
                           CurrentTime - cli_serv(acptr)->timestamp);
            } else
                send_reply(sptr, RPL_TRACESERVER, conClass, link_s[i],
                           link_u[i], cli_name(acptr),
                           (*(cli_serv(acptr))->by) ?  cli_serv(acptr)->by : "*", "*",
                           cli_name(&me), CurrentTime - cli_lasttime(acptr),
                           CurrentTime - cli_serv(acptr)->timestamp);
            cnt++;
            break;
        default:                  /* We actually shouldn't come here, -msa */
            send_reply(sptr, RPL_TRACENEWTYPE, get_client_name(acptr, HIDE_IP));
            cnt++;
            break;
        }
    }
    /*
     * Add these lines to summarize the above which can get rather long
     * and messy when done remotely - Avalon
     */
    if (IsAnOper(sptr) && doall) {
        for (cl = get_class_list(); cl; cl = cl->next) {
            if (Links(cl) > 1)
                send_reply(sptr, RPL_TRACECLASS, ConClass(cl), Links(cl) - 1);
        }
    }
    send_reply(sptr, RPL_TRACEEND);
    MyFree(link_s);
}
Example #7
0
/*
 * 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)
{
aConfItem *aconf, **pconf, *con_conf = (aConfItem *) NULL;
aClient   *cptr;
aClass    *cltmp;
int        connecting, confrq, con_class = 0;
time_t      next = 0;

   connecting = FALSE;

   Debug((DEBUG_NOTICE, "Connection check at   : %s",
	  myctime(currenttime)));

   for (aconf = conf; aconf; aconf = aconf->next) {
      /* Also when already connecting! (update holdtimes) --SRB */
      if (!(aconf->status & CONF_CONNECT_SERVER) || aconf->port <= 0)
	 continue;
      cltmp = Class (aconf);

      /*
       * * Skip this entry if the use of it is still on hold until 
       * future. Otherwise handle this entry (and set it on hold 
       * until next time). Will reset only hold times, if already 
       * made one successfull connection... [this algorithm is a bit
       * fuzzy... -- msa >;) ]
       */

      if ((aconf->hold > currenttime)) 
      {
	 if ((next > aconf->hold) || (next == 0))
	    next = aconf->hold;
	 continue;
      }

      confrq = get_con_freq(cltmp);
      aconf->hold = currenttime + confrq;

      /* Found a CONNECT config with port specified, scan clients 
       * and see if this server is already connected?
       */

      cptr = find_name(aconf->name, (aClient *) NULL);

      if (!cptr && (Links(cltmp) < MaxLinks(cltmp)) &&
	  (!connecting || (Class (cltmp) > con_class))) 
      {
	con_class = Class (cltmp);

 	con_conf = aconf;
	 /* We connect only one at time... */
	connecting = TRUE;
      }

      if ((next > aconf->hold) || (next == 0))
	 next = aconf->hold;
   }

   if (connecting) 
   {
      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;
      }
      if (connect_server(con_conf, (aClient *) NULL,
			 (struct hostent *) NULL) == 0)
	 sendto_gnotice("from %s: Connection to %s activated.", me.name, con_conf->name);
   }
   Debug((DEBUG_NOTICE, "Next connection check : %s", myctime(next)));
   return (next);
}