Esempio n. 1
0
/* send_linebuf()
 *
 * inputs	- client to send to, linebuf to attach
 * outputs	-
 * side effects - linebuf is attached to client
 */
static int
_send_linebuf(struct Client *to, buf_head_t *linebuf)
{
	if(IsMe(to))
	{
		sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send message to myself!");
		return 0;
	}

	if(!MyConnect(to) || IsIOError(to))
		return 0;

	if(rb_linebuf_len(&to->localClient->buf_sendq) > get_sendq(to))
	{
		if(IsServer(to))
		{
			sendto_realops_snomask(SNO_GENERAL, L_ALL,
					     "Max SendQ limit exceeded for %s: %u > %lu",
					     to->name,
					     rb_linebuf_len(&to->localClient->buf_sendq),
					     get_sendq(to));

			ilog(L_SERVER, "Max SendQ limit exceeded for %s: %u > %lu",
			     log_client_name(to, SHOW_IP),
			     rb_linebuf_len(&to->localClient->buf_sendq),
			     get_sendq(to));
		}

		dead_link(to, 1);
		return -1;
	}
	else
	{
		/* just attach the linebuf to the sendq instead of
		 * generating a new one
		 */
		rb_linebuf_attach(&to->localClient->buf_sendq, linebuf);
	}

	/*
	 ** Update statistics. The following is slightly incorrect
	 ** because it counts messages even if queued, but bytes
	 ** only really sent. Queued bytes get updated in SendQueued.
	 */
	to->localClient->sendM += 1;
	me.localClient->sendM += 1;
	if(rb_linebuf_len(&to->localClient->buf_sendq) > 0)
		send_queued(to);
	return 0;
}
Esempio n. 2
0
/*
 * safelist_sendq_exceeded()
 *
 * inputs       - pointer to client that needs checking
 * outputs      - 1 if a client has exceeded the reserved
 *                sendq limit, 0 if not
 * side effects - none
 *
 * When safelisting, we only use half of the SendQ at any
 * given time.
 */
static int safelist_sendq_exceeded(struct Client *client_p)
{
	if (rb_linebuf_len(&client_p->localClient->buf_sendq) > (get_sendq(client_p) / 2))
		return YES;
	else
		return NO;
}
Esempio n. 3
0
/* send_queued_write()
 *
 * inputs	- fd to have queue sent, client we're sending to
 * outputs	- contents of queue
 * side effects - write is rescheduled if queue isnt emptied
 */
void
send_queued(struct Client *to)
{
    int retlen;
#ifdef USE_IODEBUG_HOOKS
    hook_data_int hd;
#endif
    rb_fde_t *F = to->localClient->F;
    if (!F)
        return;

    /* cant write anything to a dead socket. */
    if(IsIOError(to))
        return;

    /* Something wants us to not send anything currently */
    /* if(IsCork(to))
    	return; */

    /* try to flush later when the write event resets this */
    if(IsFlush(to))
        return;

#ifdef USE_IODEBUG_HOOKS
    hd.client = to;
    if(to->localClient->buf_sendq.list.head)
        hd.arg1 = ((buf_line_t *) to->localClient->buf_sendq.list.head->data)->buf +
                  to->localClient->buf_sendq.writeofs;
#endif

    if(rb_linebuf_len(&to->localClient->buf_sendq)) {
        while ((retlen =
                    rb_linebuf_flush(F, &to->localClient->buf_sendq)) > 0) {
            /* We have some data written .. update counters */
#ifdef USE_IODEBUG_HOOKS
            hd.arg2 = retlen;
            call_hook(h_iosend_id, &hd);

            if(to->localClient->buf_sendq.list.head)
                hd.arg1 =
                    ((buf_line_t *) to->localClient->buf_sendq.list.head->
                     data)->buf + to->localClient->buf_sendq.writeofs;
#endif


            ClearFlush(to);

            to->localClient->sendB += retlen;
            me.localClient->sendB += retlen;
            if(to->localClient->sendB > 1023) {
                to->localClient->sendK += (to->localClient->sendB >> 10);
                to->localClient->sendB &= 0x03ff;	/* 2^10 = 1024, 3ff = 1023 */
            } else if(me.localClient->sendB > 1023) {
                me.localClient->sendK += (me.localClient->sendB >> 10);
                me.localClient->sendB &= 0x03ff;
            }
Esempio n. 4
0
static void
rb_helper_write_sendq(rb_fde_t *F, void *helper_ptr)
{
	rb_helper *helper = helper_ptr;
	int retlen;

	if(rb_linebuf_len(&helper->sendq) > 0)
	{
		while((retlen = rb_linebuf_flush(F, &helper->sendq)) > 0)
			;
		if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
		{
			rb_helper_restart(helper);
			return;
		}
	}

	if(rb_linebuf_len(&helper->sendq) > 0)
		rb_setselect(helper->ofd, RB_SELECT_WRITE, rb_helper_write_sendq, helper);
}
Esempio n. 5
0
char *get_client_sendq(const struct Client *client)
{
	static char buf[EXT_BUFSIZE + sizeof(CRLF)];

	if (rb_linebuf_len(&client->localClient->buf_sendq)) {
		int ret;

		memset(buf, 0, sizeof(buf));
		ret = rb_linebuf_get(&client->localClient->buf_sendq, buf, sizeof(buf), 0, 1);

		if (ok(ret > 0, MSG)) {
			return buf;
		} else {
			return "<get_client_sendq error>";
		}
	}

	return "";
}
Esempio n. 6
0
/* send_queued_write()
 *
 * inputs	- fd to have queue sent, client we're sending to
 * outputs	- contents of queue
 * side effects - write is rescheduled if queue isnt emptied
 */
void
send_queued(struct Client *to)
{
	int retlen;

	rb_fde_t *F = to->localClient->F;
	if (!F)
		return;

	/* cant write anything to a dead socket. */
	if(IsIOError(to))
		return;

	/* try to flush later when the write event resets this */
	if(IsFlush(to))
		return;

	if(rb_linebuf_len(&to->localClient->buf_sendq))
	{
		while ((retlen =
			rb_linebuf_flush(F, &to->localClient->buf_sendq)) > 0)
		{
			/* We have some data written .. update counters */
			ClearFlush(to);

			to->localClient->sendB += retlen;
			me.localClient->sendB += retlen;
			if(to->localClient->sendB > 1023)
			{
				to->localClient->sendK += (to->localClient->sendB >> 10);
				to->localClient->sendB &= 0x03ff;	/* 2^10 = 1024, 3ff = 1023 */
			}
			else if(me.localClient->sendB > 1023)
			{
				me.localClient->sendK += (me.localClient->sendB >> 10);
				me.localClient->sendB &= 0x03ff;
			}
Esempio n. 7
0
/*
** m_whowas
**      parv[1] = nickname queried
*/
static int
m_whowas(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Whowas *temp;
	int cur = 0;
	int max = -1, found = 0;
	char *p;
	const char *nick;
	char tbuf[26];
	long sendq_limit;

	static time_t last_used = 0L;

	if(MyClient(source_p) && !IsOper(source_p))
	{
		if(last_used + (parc > 3 ? ConfigFileEntry.pace_wait :
						ConfigFileEntry.pace_wait_simple
				) > rb_current_time())
		{
			sendto_one(source_p, form_str(RPL_LOAD2HI),
				   me.name, source_p->name, "WHOWAS");
			sendto_one(source_p, form_str(RPL_ENDOFWHOWAS),
				   me.name, source_p->name, parv[1]);
			return 0;
		}
		else
			last_used = rb_current_time();
	}


	if(parc > 2)
		max = atoi(parv[2]);

	if(parc > 3)
		if(hunt_server(client_p, source_p, ":%s WHOWAS %s %s :%s", 3, parc, parv))
			return 0;

	if(!MyClient(source_p) && (max <= 0 || max > 20))
		max = 20;

	if((p = strchr(parv[1], ',')))
		*p = '\0';

	nick = parv[1];

	sendq_limit = get_sendq(client_p) * 9 / 10;

	temp = WHOWASHASH[hash_whowas_name(nick)];
	found = 0;
	for (; temp; temp = temp->next)
	{
		if(!irccmp(nick, temp->name))
		{
			if(cur > 0 && rb_linebuf_len(&client_p->localClient->buf_sendq) > sendq_limit)
			{
				sendto_one(source_p, form_str(ERR_TOOMANYMATCHES),
					   me.name, source_p->name, "WHOWAS");
				break;
			}
			sendto_one(source_p, form_str(RPL_WHOWASUSER),
				   me.name, source_p->name, temp->name,
				   temp->username, temp->hostname, temp->realname);
			if (!EmptyString(temp->sockhost) &&
					strcmp(temp->sockhost, "0") &&
					show_ip_whowas(temp, source_p))
#if 0
				sendto_one(source_p, form_str(RPL_WHOWASREAL),
					   me.name, source_p->name, temp->name,
					   "<untracked>", temp->sockhost);
#else
				sendto_one_numeric(source_p, RPL_WHOISACTUALLY,
						   form_str(RPL_WHOISACTUALLY),
						   temp->name, temp->sockhost);
#endif
			if (!EmptyString(temp->suser))
				sendto_one_numeric(source_p, RPL_WHOISLOGGEDIN,
						   "%s %s :was logged in as",
						   temp->name, temp->suser);
			sendto_one_numeric(source_p, RPL_WHOISSERVER,
					   form_str(RPL_WHOISSERVER),
					   temp->name, temp->servername,
					   rb_ctime(temp->logoff, tbuf, sizeof(tbuf)));
			cur++;
			found++;
		}
		if(max > 0 && cur >= max)
			break;
	}

	if(!found)
		sendto_one(source_p, form_str(ERR_WASNOSUCHNICK),
			   me.name, source_p->name, nick);

	sendto_one(source_p, form_str(RPL_ENDOFWHOWAS),
		   me.name, source_p->name, parv[1]);
	return 0;
}