Beispiel #1
0
void
evbuffer_commit_read(struct evbuffer *evbuf, ev_ssize_t nBytes)
{
	struct evbuffer_overlapped *buf = upcast_evbuffer(evbuf);
	struct evbuffer_iovec iov[2];
	int n_vec;

	EVBUFFER_LOCK(evbuf);
	EVUTIL_ASSERT(buf->read_in_progress && !buf->write_in_progress);
	EVUTIL_ASSERT(nBytes >= 0); /* XXXX Can this be false? */

	evbuffer_unfreeze(evbuf, 0);

	iov[0].iov_base = buf->buffers[0].buf;
	if ((size_t)nBytes <= buf->buffers[0].len) {
		iov[0].iov_len = nBytes;
		n_vec = 1;
	} else {
		iov[0].iov_len = buf->buffers[0].len;
		iov[1].iov_base = buf->buffers[1].buf;
		iov[1].iov_len = nBytes - iov[0].iov_len;
		n_vec = 2;
	}

	if (evbuffer_commit_space(evbuf, iov, n_vec) < 0)
		EVUTIL_ASSERT(0); /* XXXX fail nicer. */

	pin_release(buf, EVBUFFER_MEM_PINNED_R);

	buf->read_in_progress = 0;

	_evbuffer_decref_and_unlock(evbuf);
}
Beispiel #2
0
static void
test_evbuffer_reserve_many(void *ptr)
{
	/* This is a glass-box test to handle expanding a buffer with more
	 * chunks and reallocating chunks as needed */
	struct evbuffer *buf = evbuffer_new();
	struct evbuffer_iovec v[8];
	int n;
	size_t sz;
	int add_data = ptr && !strcmp(ptr, "add");
	int fill_first = ptr && !strcmp(ptr, "fill");
	char *cp1, *cp2;

	/* When reserving the the first chunk, we just allocate it */
	n = evbuffer_reserve_space(buf, 128, v, 2);
	evbuffer_validate(buf);
	tt_int_op(n, ==, 1);
	tt_assert(v[0].iov_len >= 128);
	sz = v[0].iov_len;
	cp1 = v[0].iov_base;
	if (add_data) {
		*(char*)v[0].iov_base = 'X';
		v[0].iov_len = 1;
		n = evbuffer_commit_space(buf, v, 1);
		tt_int_op(n, ==, 0);
	} else if (fill_first) {
static void echo_read_cb(struct bufferevent *bev, void *ctx)
{
	
		char * line;
		char* retval;
		size_t len;
        /* This callback is invoked when there is data to read on bev. */
        struct evbuffer *input = bufferevent_get_input(bev);
        struct evbuffer *output = bufferevent_get_output(bev);
		struct evbuffer_iovec v[2];

		line = evbuffer_readln(input, &len, EVBUFFER_EOL_CRLF);
		retval = (char*)command_parser(line);
		//command_parser(line);
		evbuffer_reserve_space(output, strlen(retval), v, 2);
		evbuffer_add(output, retval, strlen(retval));
		evbuffer_commit_space(output, v, 1);
		
		//evbuffer_add_buffer(output, input);
		

		//evbuffer_copyout(input, line, buffer_len);
		
        /* Copy all the data from the input buffer to the output buffer. */
		printf("%s\n",line);
		free(line);    
}
Beispiel #4
0
static void encrypt_mem(redsocks_client * client,
                      char * data, size_t len,
                      struct bufferevent * to, int decrypt)
{
    ss_client *sclient = (void*)(client + 1);
    struct evbuffer_iovec vec;
    struct evbuffer * buf_out = bufferevent_get_output(to);
    size_t required;
    int rc;

    if (!len || !data)
        return;

    if (decrypt)
        required = ss_calc_buffer_size(&sclient->d_ctx, len);
    else
        required = ss_calc_buffer_size(&sclient->e_ctx, len);
    if (required && evbuffer_reserve_space(buf_out, required, &vec, 1) == 1)
    {
        if (decrypt)
            rc = ss_decrypt(&sclient->d_ctx, data, len, vec.iov_base, &vec.iov_len);
        else
            rc = ss_encrypt(&sclient->e_ctx, data, len, vec.iov_base, &vec.iov_len);
        if (!rc)
            vec.iov_len = 0;
        evbuffer_commit_space(buf_out, &vec, 1);
    }
}
Beispiel #5
0
int encode_in(Gzb64* gzb64, const unsigned char* buf, const size_t length, const bool last)
{
	int flush_type, zret;
	struct evbuffer_iovec v[2];
	int n, i, written;
	size_t n_to_add = BUFF_SIZE;

	if(last) {
		flush_type = Z_FINISH;
		gzb64->encoded_last_chunk = true;
	} else {
		flush_type = Z_NO_FLUSH;	
	}

	gzb64->gz_encode_strm.next_in = buf;
	gzb64->gz_encode_strm.avail_in = length;

	/* loop as long as more input available */
	while( 0 != gzb64->gz_encode_strm.avail_in || Z_FINISH == flush_type )
	{
		/* Reserve BUFF_SIZE bytes.*/
		n = evbuffer_reserve_space(gzb64->encode_gzout_buffer, n_to_add, v, 2);
		if (n<=0)
		   return -1; /* Unable to reserve the space for some reason. */

		for (i=0; i<n && n_to_add > 0; ++i) {
		   size_t len = v[i].iov_len;
		   if (len > n_to_add) /* Don't write more than n_to_add bytes. */
			  len = n_to_add;

			gzb64->gz_encode_strm.avail_out = len;
			gzb64->gz_encode_strm.next_out = v[i].iov_base;
			
			zret = deflate (& gzb64->gz_encode_strm, flush_type);
			if(zret < 0) zerr(zret);

			written = len - gzb64->gz_encode_strm.avail_out;
			if(DEBUG) printf("Deflate Out:%d\n", written);

		  /* If there was a problem during data generation, we can just stop
			 here; no data will be committed to the buffer. */

		   /* Set iov_len to the number of bytes we actually wrote, so we
			  don't commit too much. */
		   v[i].iov_len = written;
		}

		/* We commit the space here.  Note that we give it 'i' (the number of
		   vectors we actually used) rather than 'n' (the number of vectors we
		   had available. */
		if (evbuffer_commit_space(gzb64->encode_gzout_buffer, v, i) < 0)
		   return -1; /* Error committing */

		if( Z_FINISH == flush_type && 0 == written ) break;

	} 

	return 0;	
}
Beispiel #6
0
static enum bufferevent_filter_result
zlib_output_filter(struct evbuffer *src, struct evbuffer *dst,
    ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx)
{
	struct evbuffer_iovec v_in[1];
	struct evbuffer_iovec v_out[1];
	int nread, nwrite;
	int res, n;

	z_streamp p = ctx;

	do {
		/* let's do some compression */
		n = evbuffer_peek(src, -1, NULL, v_in, 1);
		if (n) {
			p->avail_in = v_in[0].iov_len;
			p->next_in = v_in[0].iov_base;
		} else {
			p->avail_in = 0;
			p->next_in = 0;
		}

		evbuffer_reserve_space(dst, 4096, v_out, 1);
		p->next_out = v_out[0].iov_base;
		p->avail_out = v_out[0].iov_len;

		/* we need to flush zlib if we got a flush */
		res = deflate(p, getstate(state));

		/* let's figure out how much was decompressed */
		nread = v_in[0].iov_len - p->avail_in;
		nwrite = v_out[0].iov_len - p->avail_out;

		evbuffer_drain(src, nread);
		v_out[0].iov_len = nwrite;
		evbuffer_commit_space(dst, v_out, 1);

		if (res==Z_BUF_ERROR) {
			/* We're out of space, or out of decodeable input.
			   Only if nwrite == 0 assume the latter.
			 */
			if (nwrite == 0)
				return BEV_NEED_MORE;
		} else {
			assert(res == Z_OK || res == Z_STREAM_END);
		}

	} while (evbuffer_get_length(src) > 0);

	++outfilter_calls;

	return (BEV_OK);
}
Beispiel #7
0
int encode_out_ev(Gzb64* gzb64, struct evbuffer* output)
{

	struct evbuffer_iovec v[2];
	int n, i, written;
	size_t n_to_add = BUFF_SIZE;

	/* Reserve BUFF_SIZE bytes.*/
	n = evbuffer_reserve_space(output, n_to_add, v, 2);
	if (n<=0)
	   return -1; /* Unable to reserve the space for some reason. */

	for (i=0; i<n && n_to_add > 0; ++i) {
	   size_t len = v[i].iov_len;
	   if (len > n_to_add) /* Don't write more than n_to_add bytes. */
		  len = n_to_add;
	   if ( (written = encode_out(gzb64, v[i].iov_base, len)) < 0) {
		  /* If there was a problem during data generation, we can just stop
		     here; no data will be committed to the buffer. */
		  return -1;
	   }
	   /* Set iov_len to the number of bytes we actually wrote, so we
		  don't commit too much. */
	   v[i].iov_len = written;
	}

	/* We commit the space here.  Note that we give it 'i' (the number of
	   vectors we actually used) rather than 'n' (the number of vectors we
	   had available. */
	if (evbuffer_commit_space(output, v, i) < 0)
	   return -1; /* Error committing */

	/* recurse if some bytes were retrieved */
	if( written > 0 )
		return encode_out_ev(gzb64, output);
	
	resetEncoder(gzb64);

	return 0;
}
Beispiel #8
0
static void
add_response (struct evhttp_request * req,
              struct tr_rpc_server  * server,
              struct evbuffer       * out,
              struct evbuffer       * content)
{
  const char * key = "Accept-Encoding";
  const char * encoding = evhttp_find_header (req->input_headers, key);
  const int do_compress = encoding && strstr (encoding, "gzip");

  if (!do_compress)
    {
      evbuffer_add_buffer (out, content);
    }
  else
    {
      int state;
      struct evbuffer_iovec iovec[1];
      void * content_ptr = evbuffer_pullup (content, -1);
      const size_t content_len = evbuffer_get_length (content);

      if (!server->isStreamInitialized)
        {
          int compressionLevel;

          server->isStreamInitialized = true;
          server->stream.zalloc = (alloc_func) Z_NULL;
          server->stream.zfree = (free_func) Z_NULL;
          server->stream.opaque = (voidpf) Z_NULL;

          /* zlib's manual says: "Add 16 to windowBits to write a simple gzip header
           * and trailer around the compressed data instead of a zlib wrapper." */
#ifdef TR_LIGHTWEIGHT
          compressionLevel = Z_DEFAULT_COMPRESSION;
#else
          compressionLevel = Z_BEST_COMPRESSION;
#endif
          deflateInit2 (&server->stream, compressionLevel, Z_DEFLATED, 15+16, 8, Z_DEFAULT_STRATEGY);
        }

      server->stream.next_in = content_ptr;
      server->stream.avail_in = content_len;

      /* allocate space for the raw data and call deflate () just once --
       * we won't use the deflated data if it's longer than the raw data,
       * so it's okay to let deflate () run out of output buffer space */
      evbuffer_reserve_space (out, content_len, iovec, 1);
      server->stream.next_out = iovec[0].iov_base;
      server->stream.avail_out = iovec[0].iov_len;
      state = deflate (&server->stream, Z_FINISH);

      if (state == Z_STREAM_END)
        {
          iovec[0].iov_len -= server->stream.avail_out;

#if 0
          fprintf (stderr, "compressed response is %.2f of original (raw==%zu bytes; compressed==%zu)\n",
                   (double)evbuffer_get_length (out)/content_len,
                   content_len, evbuffer_get_length (out));
#endif
          evhttp_add_header (req->output_headers,
                             "Content-Encoding", "gzip");
        }
      else
        {
          memcpy (iovec[0].iov_base, content_ptr, content_len);
          iovec[0].iov_len = content_len;
        }

      evbuffer_commit_space (out, iovec, 1);
      deflateReset (&server->stream);
    }
}
Beispiel #9
0
static int decode(Gzb64* gzb64, bool last)
{
	int b64in_size;
	struct evbuffer_iovec v[2];
	int n, i;
	size_t n_to_add = BUFF_SIZE;

	if( last ) {
		b64in_size = evbuffer_get_length(gzb64->decode_input_buffer); /* dump everything in */		
		gzb64->decoded_last_chunk = true;	
	} else {
		int contiguous = evbuffer_get_contiguous_space(gzb64->decode_input_buffer);	
		b64in_size = contiguous - (contiguous % 4); /* must be mutliple of 4 */	 
	}

	if(DEBUG) printf("Decode In:%zu\n", evbuffer_get_length(gzb64->decode_input_buffer));

	unsigned char* b64in_buf = evbuffer_pullup(gzb64->decode_input_buffer, b64in_size);
	BIO *b64_src_temp = BIO_new_mem_buf(b64in_buf, b64in_size);
	gzb64->b64_decoder = BIO_push(gzb64->b64_decoder, b64_src_temp);

	int b64_output_len = BUFF_SIZE;

	while(b64_output_len == BUFF_SIZE) {

		/* Reserve BUFF_SIZE bytes.*/
		n = evbuffer_reserve_space(gzb64->decode_output_buffer, n_to_add, v, 2);
		if (n<=0)
		   return -1; /* Unable to reserve the space for some reason. */

		for (i=0; i<n && n_to_add > 0; ++i) {
		   size_t len = v[i].iov_len;
		   if (len > n_to_add) /* Don't write more than n_to_add bytes. */
			  len = n_to_add;

		   b64_output_len = BIO_read(gzb64->b64_decoder, v[i].iov_base, len);

		   if ( b64_output_len < 0) {
			  /* If there was a problem during data generation, we can just stop
				 here; no data will be committed to the buffer. */
			  return -1;
		   }
		   /* Set iov_len to the number of bytes we actually wrote, so we
			  don't commit too much. */
		   v[i].iov_len = b64_output_len;
			if(DEBUG) printf("Decode B64 Out:%d\n", b64_output_len);
		}

		/* We commit the space here.  Note that we give it 'i' (the number of
		   vectors we actually used) rather than 'n' (the number of vectors we
		   had available. */
		if (evbuffer_commit_space(gzb64->decode_output_buffer, v, i) < 0)
		   return -1; /* Error committing */
	}

	if(DEBUG) printf("Inflate In:%zu\n", evbuffer_get_length(gzb64->decode_output_buffer));

	BIO_pop(gzb64->b64_decoder);
	BIO_free(b64_src_temp);
	BIO_reset(gzb64->b64_decoder);

	evbuffer_drain(gzb64->decode_input_buffer, b64in_size);
	
	return 0;
}