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);    
}
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) {
Exemple #3
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);
    }
}
Exemple #4
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;	
}
Exemple #5
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);
}
Exemple #6
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;
}
Exemple #7
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);
    }
}
Exemple #8
0
static void
test_evbuffer_reserve2(void *ptr)
{
	/* Test the two-vector cases of reserve/commit. */
	struct evbuffer *buf = evbuffer_new();
	int n, i;
	struct evbuffer_iovec v[2];
	size_t remaining;
	char *cp, *cp2;

	/* First chunk will necessarily be one chunk. Use 512 bytes of it.*/
	n = evbuffer_reserve_space(buf, 1024, v, 2);
	tt_int_op(n, ==, 1);
	tt_int_op(evbuffer_get_length(buf), ==, 0);
	tt_assert(v[0].iov_base != NULL);
	tt_int_op(v[0].iov_len, >=, 1024);
	memset(v[0].iov_base, 'X', 512);
	cp = v[0].iov_base;
	remaining = v[0].iov_len - 512;
	v[0].iov_len = 512;
	tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
	tt_int_op(evbuffer_get_length(buf), ==, 512);

	/* Ask for another same-chunk request, in an existing chunk. Use 8
	 * bytes of it. */
	n = evbuffer_reserve_space(buf, 32, v, 2);
	tt_int_op(n, ==, 1);
	tt_assert(cp + 512 == v[0].iov_base);
	tt_int_op(remaining, ==, v[0].iov_len);
	memset(v[0].iov_base, 'Y', 8);
	v[0].iov_len = 8;
	tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
	tt_int_op(evbuffer_get_length(buf), ==, 520);
	remaining -= 8;

	/* Now ask for a request that will be split. Use only one byte of it,
	   though. */
	n = evbuffer_reserve_space(buf, remaining+64, v, 2);
	tt_int_op(n, ==, 2);
	tt_assert(cp + 520 == v[0].iov_base);
	tt_int_op(remaining, ==, v[0].iov_len);
	tt_assert(v[1].iov_base);
	tt_assert(v[1].iov_len >= 64);
	cp2 = v[1].iov_base;
	memset(v[0].iov_base, 'Z', 1);
	v[0].iov_len = 1;
	tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
	tt_int_op(evbuffer_get_length(buf), ==, 521);
	remaining -= 1;

	/* Now ask for a request that will be split. Use some of the first
	 * part and some of the second. */
	n = evbuffer_reserve_space(buf, remaining+64, v, 2);
	tt_int_op(n, ==, 2);
	tt_assert(cp + 521 == v[0].iov_base);
	tt_int_op(remaining, ==, v[0].iov_len);
	tt_assert(v[1].iov_base == cp2);
	tt_assert(v[1].iov_len >= 64);
	memset(v[0].iov_base, 'W', 400);
	v[0].iov_len = 400;
	memset(v[1].iov_base, 'x', 60);
	v[1].iov_len = 60;
	tt_int_op(0, ==, evbuffer_commit_space(buf, v, 2));
	tt_int_op(evbuffer_get_length(buf), ==, 981);


	/* Now peek to make sure stuff got made how we like. */
	memset(v,0,sizeof(v));
	n = evbuffer_peek(buf, -1, NULL, v, 2);
	tt_int_op(n, ==, 2);
	tt_int_op(v[0].iov_len, ==, 921);
	tt_int_op(v[1].iov_len, ==, 60);

	cp = v[0].iov_base;
	for (i=0; i<512; ++i)
		tt_int_op(cp[i], ==, 'X');
	for (i=512; i<520; ++i)
		tt_int_op(cp[i], ==, 'Y');
	for (i=520; i<521; ++i)
		tt_int_op(cp[i], ==, 'Z');
	for (i=521; i<921; ++i)
		tt_int_op(cp[i], ==, 'W');

	cp = v[1].iov_base;
	for (i=0; i<60; ++i)
		tt_int_op(cp[i], ==, 'x');

end:
	evbuffer_free(buf);
}
Exemple #9
0
static void
test_evbuffer(void *ptr)
{
	static char buffer[512], *tmp;
	struct evbuffer *evb = evbuffer_new();
	struct evbuffer *evb_two = evbuffer_new();
	size_t sz_tmp;
	int i;

	evbuffer_validate(evb);
	evbuffer_add_printf(evb, "%s/%d", "hello", 1);
	evbuffer_validate(evb);

	tt_assert(evbuffer_get_length(evb) == 7);
	tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "hello/1", 1));

	evbuffer_add_buffer(evb, evb_two);
	evbuffer_validate(evb);

	evbuffer_drain(evb, strlen("hello/"));
	evbuffer_validate(evb);
	tt_assert(evbuffer_get_length(evb) == 1);
	tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1", 1));

	evbuffer_add_printf(evb_two, "%s", "/hello");
	evbuffer_validate(evb);
	evbuffer_add_buffer(evb, evb_two);
	evbuffer_validate(evb);

	tt_assert(evbuffer_get_length(evb_two) == 0);
	tt_assert(evbuffer_get_length(evb) == 7);
	tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1/hello", 7) != 0);

	memset(buffer, 0, sizeof(buffer));
	evbuffer_add(evb, buffer, sizeof(buffer));
	evbuffer_validate(evb);
	tt_assert(evbuffer_get_length(evb) == 7 + 512);

	tmp = (char *)evbuffer_pullup(evb, 7 + 512);
	tt_assert(tmp);
	tt_assert(!strncmp(tmp, "1/hello", 7));
	tt_assert(!memcmp(tmp + 7, buffer, sizeof(buffer)));
	evbuffer_validate(evb);

	evbuffer_prepend(evb, "something", 9);
	evbuffer_validate(evb);
	evbuffer_prepend(evb, "else", 4);
	evbuffer_validate(evb);

	tmp = (char *)evbuffer_pullup(evb, 4 + 9 + 7);
	tt_assert(!strncmp(tmp, "elsesomething1/hello", 4 + 9 + 7));
	evbuffer_validate(evb);

	evbuffer_drain(evb, -1);
	evbuffer_validate(evb);
	evbuffer_drain(evb_two, -1);
	evbuffer_validate(evb);

	for (i = 0; i < 3; ++i) {
		evbuffer_add(evb_two, buffer, sizeof(buffer));
		evbuffer_validate(evb_two);
		evbuffer_add_buffer(evb, evb_two);
		evbuffer_validate(evb);
		evbuffer_validate(evb_two);
	}

	tt_assert(evbuffer_get_length(evb_two) == 0);
	tt_assert(evbuffer_get_length(evb) == i * sizeof(buffer));

	/* test remove buffer */
	sz_tmp = (size_t)(sizeof(buffer)*2.5);
	evbuffer_remove_buffer(evb, evb_two, sz_tmp);
	tt_assert(evbuffer_get_length(evb_two) == sz_tmp);
	tt_assert(evbuffer_get_length(evb) == sizeof(buffer) / 2);
	evbuffer_validate(evb);

	if (memcmp(evbuffer_pullup(
			   evb, -1), buffer, sizeof(buffer) / 2) != 0 ||
	    memcmp(evbuffer_pullup(
			   evb_two, -1), buffer, sizeof(buffer) != 0))
		tt_abort_msg("Pullup did not preserve content");

	evbuffer_validate(evb);


	/* testing one-vector reserve and commit */
	{
		struct evbuffer_iovec v[1];
		char *buf;
		int i, j, r;

		for (i = 0; i < 3; ++i) {
			r = evbuffer_reserve_space(evb, 10000, v, 1);
			tt_int_op(r, ==, 1);
			tt_assert(v[0].iov_len >= 10000);
			tt_assert(v[0].iov_base != NULL);

			evbuffer_validate(evb);
			buf = v[0].iov_base;
			for (j = 0; j < 10000; ++j) {
				buf[j] = j;
			}
			evbuffer_validate(evb);

			tt_int_op(evbuffer_commit_space(evb, v, 1), ==, 0);
			evbuffer_validate(evb);

			tt_assert(evbuffer_get_length(evb) >= 10000);

			evbuffer_drain(evb, j * 5000);
			evbuffer_validate(evb);
		}
	}

 end:
	evbuffer_free(evb);
	evbuffer_free(evb_two);
}
		v[0].iov_len = 1;
		n = evbuffer_commit_space(buf, v, 1);
		tt_int_op(n, ==, 0);
	} else if (fill_first) {
		memset(v[0].iov_base, 'X', v[0].iov_len);
		n = evbuffer_commit_space(buf, v, 1);
		tt_int_op(n, ==, 0);
		n = evbuffer_reserve_space(buf, 128, v, 2);
		tt_int_op(n, ==, 1);
		sz = v[0].iov_len;
		tt_assert(v[0].iov_base != cp1);
		cp1 = v[0].iov_base;
	}

	/* Make another chunk get added. */
	n = evbuffer_reserve_space(buf, sz+128, v, 2);
	evbuffer_validate(buf);
	tt_int_op(n, ==, 2);
	sz = v[0].iov_len + v[1].iov_len;
	tt_int_op(sz, >=, v[0].iov_len+128);
	if (add_data) {
		tt_assert(v[0].iov_base == cp1 + 1);
	} else {
		tt_assert(v[0].iov_base == cp1);
	}
	cp1 = v[0].iov_base;
	cp2 = v[1].iov_base;

	/* And a third chunk. */
	n = evbuffer_reserve_space(buf, sz+128, v, 3);
	evbuffer_validate(buf);
Exemple #11
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;
}