コード例 #1
0
ファイル: zip.c プロジェクト: Adam-/unrealircd
/*
** zip_buffer
**      Zip the content of cptr->zip->outbuf and of the buffer,
**      put anything left in cptr->zip->outbuf, update cptr->zip->outcount
**
**      if flush is set, then all available data will be compressed,
**      otherwise, compression only occurs if there's enough to compress,
**      or if we are reaching the maximum allowed size during a connect burst.
**
**      will return the uncompressed buffer, length will be updated.
**      if a fatal error occurs, length will be set to -1
*/
char *zip_buffer(aClient *cptr, char *buffer, int *length, int flush)
{
  z_stream *zout = cptr->zip->out;
  int   r;

  if (buffer)
    {
      /* concatenate buffer in cptr->zip->outbuf */
      memcpy((void *)(cptr->zip->outbuf + cptr->zip->outcount), (void *)buffer,
             *length );
      cptr->zip->outcount += *length;
    }
  *length = 0;

#if 0
  if (!flush && ((cptr->zip->outcount < ZIP_MINIMUM) ||
                 ((cptr->zip->outcount < (ZIP_MAXIMUM - BUFSIZE)) &&
                  CBurst(cptr))))
	/* Implement this? more efficient? or not? -- Syzop */
#else
  if (!flush && (cptr->zip->outcount < ZIP_MINIMUM))
#endif
    return((char *)NULL);

  zout->next_in = (Bytef *) cptr->zip->outbuf;
  zout->avail_in = cptr->zip->outcount;
  zout->next_out = (Bytef *) zipbuf;
  zout->avail_out = ZIP_BUFFER_SIZE;

  switch (r = deflate(zout, Z_PARTIAL_FLUSH))
    {
    case Z_OK:
      if (zout->avail_in)
        {
          /* can this occur?? I hope not... */
          sendto_realops("deflate() didn't process all available data!");
        }
      cptr->zip->outcount = 0;
      *length = ZIP_BUFFER_SIZE - zout->avail_out;
      return zipbuf;

    default: /* error ! */
      sendto_realops("deflate() error(%d): %s", r, (zout->msg) ? zout->msg : "?");
      *length = -1;
      break;
    }
  return((char *)NULL);
}
コード例 #2
0
ファイル: send.c プロジェクト: ahf/irc
/*
** send_message
**	Internal utility which delivers one message buffer to the
**	socket. Takes care of the error handling and buffering, if
**	needed.
**	if ZIP_LINKS is defined, the message will eventually be compressed,
**	anything stored in the sendQ is compressed.
**
**	If msg is a null pointer, we are flushing connection
*/
int	send_message(aClient *to, char *msg, int len)
{
	int i;

	Debug((DEBUG_SEND,"Sending %s %d [%s] ", to->name, to->fd, msg));

	if (to->from)
		to = to->from;
	if (to->fd < 0)
	    {
		Debug((DEBUG_ERROR,
		       "Local socket %s with negative fd... AARGH!",
		      to->name));
	    }
	if (IsMe(to))
	    {
		sendto_flag(SCH_ERROR, "Trying to send to myself! [%s]", msg);
		return 0;
	    }
	if (IsDead(to))
		return 0; /* This socket has already been marked as dead */
	if (DBufLength(&to->sendQ) > (i=get_sendq(to, CBurst(to))))
	{
		to->exitc = EXITC_SENDQ;
		if (IsService(to) || IsServer(to))
		{
			return dead_link(to,
				"Max SendQ limit exceeded for %s: %d > %d",
				get_client_name(to, FALSE),
				DBufLength(&to->sendQ), i);
		}
		return dead_link(to, "Max Sendq exceeded");
	}
# ifdef	ZIP_LINKS
	/*
	** data is first stored in to->zip->outbuf until
	** it's big enough to be compressed and stored in the sendq.
	** send_queued is then responsible to never let the sendQ
	** be empty and to->zip->outbuf not empty.
	*/
	if (to->flags & FLAGS_ZIP)
		msg = zip_buffer(to, msg, &len, 0);

# endif	/* ZIP_LINKS */
tryagain:
	if (len && (i = dbuf_put(&to->sendQ, msg, len)) < 0)
	{
		if (i == -2	/* Poolsize was exceeded. */
#ifdef POOLSIZE_LIMITED
			/*
			** Defining this retains old ircd behaviour (will
			** allow client quit with buffer allocation error
			** as a result of poolsize starvation). As it may
			** happen to all clients on a big channel without
			** their fault, I think this is not right.
			** In the long run it should not matter (poolsize
			** or memory usage-wise), because if client lacks
			** the poolsize, the poolsize is too small anyway
			** and next netburst would probably make it grow.
			** IMO increasing poolsize with no limits is good
			** for clients -- hence this is not defined. --B.
			*/
			&& CBurst(to)
#endif
			)
		{
			/* Anyway, 10% increase. */
			poolsize *= 1.1;
			sendto_flag(SCH_NOTICE,
				    "New poolsize %u. (reached)",
				    poolsize);
			istat.is_dbufmore++;
			goto tryagain;
		}
		else
		{
			to->exitc = EXITC_MBUF;
			return dead_link(to,
				"Buffer allocation error for %s",
				get_client_name(to, FALSE));
		}
	}
	/*
	** 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->sendM += 1;
	me.sendM += 1;
	if (to->acpt != &me)
		to->acpt->sendM += 1;
	/*
	** This little bit is to stop the sendQ from growing too large when
	** there is no need for it to. Thus we call send_queued() every time
	** 2k has been added to the queue since the last non-fatal write.
	** Also stops us from deliberately building a large sendQ and then
	** trying to flood that link with data (possible during the net
	** relinking done by servers with a large load).
	*/
	if (DBufLength(&to->sendQ)/1024 > to->lastsq)
		send_queued(to);
	return 0;
}