예제 #1
0
int timestamp_get_new(struct sdirs *sdirs,
	char *buf, size_t s, char *bufforfile, size_t bs, struct conf **cconfs)
{
	time_t t=0;
	unsigned long index=0;
	struct bu *bu=NULL;
	struct bu *bu_list=NULL;
	const struct tm *ctm=NULL;

	// Want to prefix the timestamp with an index that increases by
	// one each time. This makes it far more obvious which backup depends
	// on which - even if the system clock moved around. Take that,
	// bacula!

	// This function orders the array with the highest index number last.
	if(bu_get_list(sdirs, &bu_list)) return -1;
	for(bu=bu_list; bu; bu=bu->next) if(!bu->next) index=bu->bno;

	bu_list_free(&bu_list);

	time(&t);
	ctm=localtime(&t);
        // Windows does not like the %T strftime format option - you get
        // complaints under gdb.
	index++;

	write_to_buf(buf, s, index, NULL, ctm);
	write_to_buf(bufforfile, bs, index,
		get_string(cconfs[OPT_TIMESTAMP_FORMAT]), ctm);

	return 0;
}
예제 #2
0
int call_callback(struct fd_state *state, const char *path, char *sparams, char *scookies) {
    assert(state && path);
    struct callback_elem *elem = callback_head;
    while (elem) {
        if (strcmp(path, elem->path) == 0) {
            struct lh_response response;
            response.header[0] = 0;
            response.header_len = 0;
			response.body[0] = 0;
			response.body_len = 0;
            
            struct lh_kv_elem *params = parse_url_params(sparams);
            struct lh_kv_elem *cookies = parse_cookies(scookies);
            elem->callback(params, cookies, &response);
            free_kvs(params);
            free_kvs(cookies);
            
            write_response_header(state, "application/json", response.body_len, response.header);
			if (response.header_len > 0)
				write_to_buf(state, response.header, response.header_len);
            if (response.body_len > 0)
                write_to_buf(state, response.body, response.body_len);
            return 1;
        }
        elem = elem->next;
    }
    return 0;
}
예제 #3
0
static void
test_buffers_zlib_fin_at_chunk_end(void *arg)
{
  char *msg = NULL;
  char *contents = NULL;
  char *expanded = NULL;
  buf_t *buf = NULL;
  tor_zlib_state_t *zlib_state = NULL;
  size_t out_len, in_len;
  size_t sz, headerjunk;
  (void) arg;

  buf = buf_new_with_capacity(128); /* will round up */
  sz = buf_get_default_chunk_size(buf);
  msg = tor_malloc_zero(sz);

  write_to_buf(msg, 1, buf);
  tt_assert(buf->head);

  /* Fill up the chunk so the zlib stuff won't fit in one chunk. */
  tt_uint_op(buf->head->memlen, OP_LT, sz);
  headerjunk = buf->head->memlen - 7;
  write_to_buf(msg, headerjunk-1, buf);
  tt_uint_op(buf->head->datalen, OP_EQ, headerjunk);
  tt_uint_op(buf_datalen(buf), OP_EQ, headerjunk);
  /* Write an empty string, with finalization on. */
  zlib_state = tor_zlib_new(1, ZLIB_METHOD, HIGH_COMPRESSION);
  tt_int_op(write_to_buf_zlib(buf, zlib_state, "", 0, 1), OP_EQ, 0);

  in_len = buf_datalen(buf);
  contents = tor_malloc(in_len);

  tt_int_op(fetch_from_buf(contents, in_len, buf), OP_EQ, 0);

  tt_uint_op(in_len, OP_GT, headerjunk);

  tt_int_op(0, OP_EQ, tor_gzip_uncompress(&expanded, &out_len,
                                  contents + headerjunk, in_len - headerjunk,
                                  ZLIB_METHOD, 1,
                                  LOG_WARN));

  tt_int_op(out_len, OP_EQ, 0);
  tt_assert(expanded);

 done:
  buf_free(buf);
  tor_zlib_free(zlib_state);
  tor_free(contents);
  tor_free(expanded);
  tor_free(msg);
}
예제 #4
0
/* Simple connection_write_to_buf_impl_ replacement that unconditionally
 * writes to outbuf. */
static void
connection_write_to_buf_impl_replacement(const char *string, size_t len,
                                         connection_t *conn, int zlib)
{
  (void) zlib;

  tor_assert(string);
  tor_assert(conn);
  write_to_buf(string, len, conn->outbuf);
}
예제 #5
0
void
connection_write_to_buf_mock(const char *string, size_t len,
                             connection_t *conn, int zlib)
{
  (void) zlib;

  tor_assert(string);
  tor_assert(conn);

  write_to_buf(string, len, conn->outbuf);
}
예제 #6
0
static int write_response_header(struct fd_state *state, const char* mime, int body_len, const char* user_header) {
    assert(state && user_header && mime);
    char buf[HEADER_BUF_SIZE] = {0};
    
    const char* fmt =
        "HTTP/1.1 200 OK\r\n" \
        "Content-Type: %s\r\n" \
        "Content-Length: %u\r\n" \
		"%s\r\n";
    
    snprintf(buf, sizeof(buf), fmt, mime, body_len, user_header);
    write_to_buf(state, buf, strlen(buf));
    return 0;
}
// terminate all profiling by critical error
// TODO: don't send data to host
static void terminate_error(char *errstr, int send_to_host)
{
	LOGE("termination all with err '%s'\n", errstr);
	struct msg_data_t *msg = NULL;
	if (send_to_host != 0) {
		msg = gen_message_error(errstr);
		if (msg) {
			if (write_to_buf(msg) != 0)
				LOGE("write to buf fail\n");
			free_msg_data(msg);
		} else {
			LOGI("cannot generate error message\n");
		}
	}
	terminate_all();
}
예제 #8
0
파일: console.c 프로젝트: LastRitter/GridOS
static inline void set_line_prev_idx(unsigned int line_idx)
{
	int i = 0;
	char *c;
	
	
	c = (char*)&line_idx;

	for (i = 0; i < sizeof(unsigned int); i++ )
	{		
		write_to_buf(*c);
		c++;
	}		

	return;
}
예제 #9
0
파일: console.c 프로젝트: LastRitter/GridOS
static unsigned int cp_to_buffer(char* buf)
{
	char *p_string = buf;
	unsigned int next_line_idx_idx;
	
	while (*p_string != '\0')
	{
		write_to_buf(*p_string);
		if (*p_string == '\n' )
		{
			set_line_prev_idx(dsp_ctx.buffer.tail_line);
			dsp_ctx.buffer.lastchar = get_buf_idx(dsp_ctx.buffer.lastchar + sizeof(unsigned int));
			next_line_idx_idx = get_buf_idx(dsp_ctx.buffer.tail_line - sizeof(unsigned int));
			set_line_next_idx(next_line_idx_idx, dsp_ctx.buffer.lastchar);
			dsp_ctx.buffer.tail_line = dsp_ctx.buffer.lastchar;
			p_string++;
			break;
		}
		p_string++;	
	}
	return (unsigned int)((unsigned long)p_string - (unsigned long)buf);
}
예제 #10
0
static void
test_buffer_ext_or_cmd(void *arg)
{
    ext_or_cmd_t *cmd = NULL;
    buf_t *buf = buf_new();
    char *tmp = NULL;
    (void) arg;

    /* Empty -- should give "not there. */
    tt_int_op(0, OP_EQ, fetch_ext_or_command_from_buf(buf, &cmd));
    tt_ptr_op(NULL, OP_EQ, cmd);

    /* Three bytes: shouldn't work. */
    write_to_buf("\x00\x20\x00", 3, buf);
    tt_int_op(0, OP_EQ, fetch_ext_or_command_from_buf(buf, &cmd));
    tt_ptr_op(NULL, OP_EQ, cmd);
    tt_int_op(3, OP_EQ, buf_datalen(buf));

    /* 0020 0000: That's a nil command. It should work. */
    write_to_buf("\x00", 1, buf);
    tt_int_op(1, OP_EQ, fetch_ext_or_command_from_buf(buf, &cmd));
    tt_ptr_op(NULL, OP_NE, cmd);
    tt_int_op(0x20, OP_EQ, cmd->cmd);
    tt_int_op(0, OP_EQ, cmd->len);
    tt_int_op(0, OP_EQ, buf_datalen(buf));
    ext_or_cmd_free(cmd);
    cmd = NULL;

    /* Now try a length-6 command with one byte missing. */
    write_to_buf("\x10\x21\x00\x06""abcde", 9, buf);
    tt_int_op(0, OP_EQ, fetch_ext_or_command_from_buf(buf, &cmd));
    tt_ptr_op(NULL, OP_EQ, cmd);
    write_to_buf("f", 1, buf);
    tt_int_op(1, OP_EQ, fetch_ext_or_command_from_buf(buf, &cmd));
    tt_ptr_op(NULL, OP_NE, cmd);
    tt_int_op(0x1021, OP_EQ, cmd->cmd);
    tt_int_op(6, OP_EQ, cmd->len);
    tt_mem_op("abcdef", OP_EQ, cmd->body, 6);
    tt_int_op(0, OP_EQ, buf_datalen(buf));
    ext_or_cmd_free(cmd);
    cmd = NULL;

    /* Now try a length-10 command with 4 extra bytes. */
    write_to_buf("\xff\xff\x00\x0aloremipsum\x10\x00\xff\xff", 18, buf);
    tt_int_op(1, OP_EQ, fetch_ext_or_command_from_buf(buf, &cmd));
    tt_ptr_op(NULL, OP_NE, cmd);
    tt_int_op(0xffff, OP_EQ, cmd->cmd);
    tt_int_op(10, OP_EQ, cmd->len);
    tt_mem_op("loremipsum", OP_EQ, cmd->body, 10);
    tt_int_op(4, OP_EQ, buf_datalen(buf));
    ext_or_cmd_free(cmd);
    cmd = NULL;

    /* Finally, let's try a maximum-length command. We already have the header
     * waiting. */
    tt_int_op(0, OP_EQ, fetch_ext_or_command_from_buf(buf, &cmd));
    tmp = tor_malloc_zero(65535);
    write_to_buf(tmp, 65535, buf);
    tt_int_op(1, OP_EQ, fetch_ext_or_command_from_buf(buf, &cmd));
    tt_ptr_op(NULL, OP_NE, cmd);
    tt_int_op(0x1000, OP_EQ, cmd->cmd);
    tt_int_op(0xffff, OP_EQ, cmd->len);
    tt_mem_op(tmp, OP_EQ, cmd->body, 65535);
    tt_int_op(0, OP_EQ, buf_datalen(buf));
    ext_or_cmd_free(cmd);
    cmd = NULL;

done:
    ext_or_cmd_free(cmd);
    buf_free(buf);
    tor_free(tmp);
}
예제 #11
0
파일: webproxy.c 프로젝트: EESC/cn-atda6
void do_proxy(int clifd, const struct sockaddr_in *cliaddr, int pid) {
    /* get the request from the client */
    char *request;
    int request_len;
    request = calloc(MAXLINE, sizeof(char));
    request_len = Read(clifd, request, MAXLINE);

    /* get the request line, header lines and entity body */
    const char *request_line, *header_lines, *body;
    int rlen, hlen, blen;
    separate_http_message(request, request_len, &request_line, &rlen, &header_lines, &hlen, &body, &blen);
    
    /* get header fields */
    struct header_field *header_fields;
    header_fields = get_header_fields(header_lines, hlen);

    /* remove Connection and Proxy-Connection from header fields */
    remove_header_field(&header_fields, "Connection");
    remove_header_field(&header_fields, "Proxy-Connection");

    /* get the hostname of the server */
    const struct header_field *host_header_field;
    char *host;
    const char *p_host, *method, *url, *version;
    int hostlen, methodlen, urllen, versionlen;
    if ((host_header_field = get_header_field(header_fields, "Host")) == NULL) {
	get_start_fields(request_line, rlen, &method, &methodlen, &url, &urllen, &version, &versionlen);
	get_host_from_url(url, &p_host, &hostlen);
    } else {
	p_host = host_header_field->value;
	hostlen = host_header_field->vlen;
    }
    host = calloc(1, hostlen + 1);
    memcpy(host, p_host, hostlen);

    /* connect to the server */
    int servfd;
    struct sockaddr_in servaddr;
    socklen_t servaddrlen;
    struct addrinfo hints, *result;
    fprintf(stdout, "---pid=%d, Connect to the server\n", pid);
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    getaddrinfo(host, "http", &hints, &result);
    memcpy(&servaddr, result->ai_addr, sizeof(servaddr));
    servaddrlen = result->ai_addrlen;
    freeaddrinfo(result);

    servfd = Socket(AF_INET, SOCK_STREAM, 0);
    Connect(servfd, (struct sockaddr *)&servaddr, servaddrlen);

    /* assemble the new request, assuming that the whole request is less than 4096 bytes */
    char *new_request, *bufpos;
    int new_request_len;
    struct header_field *iter_header_field;
    new_request = calloc(MAXLINE, sizeof(char));
    new_request_len = 0;
    bufpos = new_request;
    bufpos = write_to_buf(bufpos, request_line, rlen);
    bufpos = write_to_buf(bufpos, "\r\n", 2);
    new_request_len += rlen + 2;
    for (iter_header_field = header_fields; iter_header_field; iter_header_field = iter_header_field->next) {
	bufpos = write_to_buf(bufpos, iter_header_field->name, iter_header_field->nlen);
	bufpos = write_to_buf(bufpos, ": ", 2);
	bufpos = write_to_buf(bufpos, iter_header_field->value, iter_header_field->vlen);
	bufpos = write_to_buf(bufpos, "\r\n", 2);
	new_request_len += iter_header_field->nlen + iter_header_field->vlen + 4;
    }
    bufpos = write_to_buf(bufpos, "\r\n", 2);
    bufpos = write_to_buf(bufpos, body, blen);
    new_request_len += blen + 2;

    /* send the new request to the server */
    fprintf(stdout, "---pid=%d, Send the new request to the server\n", pid);
    Write(servfd, new_request, new_request_len);

    /* get and send back the response */
    char *response;
    int response_len;
    fprintf(stdout, "---pid=%d, Send the response back to the client\n", pid);
    response = calloc(MAXLINE, sizeof(char));

    while ((response_len = Read(servfd, response, MAXLINE)) > 0) {
	fprintf(stdout, "---pid=%d, %d bytes received from the server\n", pid, response_len);
	Write(clifd, response, response_len);
    }
    
    /* close the server socket */
    fprintf(stdout, "---pid=%d, Close the server socket\n", pid);
    close(servfd);

    /* release memory */
    struct header_field *next_header_field;
    free(request);
    free(new_request);
    free(response);
    free(host);
    for (iter_header_field = header_fields; iter_header_field; iter_header_field = next_header_field) {
	next_header_field = iter_header_field->next;
	free(iter_header_field);
    }
}
예제 #12
0
static void
test_buffer_allocation_tracking(void *arg)
{
  char *junk = tor_malloc(16384);
  buf_t *buf1 = NULL, *buf2 = NULL;
  int i;

  (void)arg;

  crypto_rand(junk, 16384);
  tt_int_op(buf_get_total_allocation(), OP_EQ, 0);

  buf1 = buf_new();
  tt_assert(buf1);
  buf2 = buf_new();
  tt_assert(buf2);

  tt_int_op(buf_allocation(buf1), OP_EQ, 0);
  tt_int_op(buf_get_total_allocation(), OP_EQ, 0);

  write_to_buf(junk, 4000, buf1);
  write_to_buf(junk, 4000, buf1);
  write_to_buf(junk, 4000, buf1);
  write_to_buf(junk, 4000, buf1);
  tt_int_op(buf_allocation(buf1), OP_EQ, 16384);
  fetch_from_buf(junk, 100, buf1);
  tt_int_op(buf_allocation(buf1), OP_EQ, 16384); /* still 4 4k chunks */

  tt_int_op(buf_get_total_allocation(), OP_EQ, 16384);

  fetch_from_buf(junk, 4096, buf1); /* drop a 1k chunk... */
  tt_int_op(buf_allocation(buf1), OP_EQ, 3*4096); /* now 3 4k chunks */

  tt_int_op(buf_get_total_allocation(), OP_EQ, 12288); /* that chunk was really
                                                       freed. */

  write_to_buf(junk, 4000, buf2);
  tt_int_op(buf_allocation(buf2), OP_EQ, 4096); /* another 4k chunk. */
  /*
   * We bounce back up to 16384 by allocating a new chunk.
   */
  tt_int_op(buf_get_total_allocation(), OP_EQ, 16384);
  write_to_buf(junk, 4000, buf2);
  tt_int_op(buf_allocation(buf2), OP_EQ, 8192); /* another 4k chunk. */
  tt_int_op(buf_get_total_allocation(),
            OP_EQ, 5*4096); /* that chunk was new. */

  /* Make a really huge buffer */
  for (i = 0; i < 1000; ++i) {
    write_to_buf(junk, 4000, buf2);
  }
  tt_int_op(buf_allocation(buf2), OP_GE, 4008000);
  tt_int_op(buf_get_total_allocation(), OP_GE, 4008000);
  buf_free(buf2);
  buf2 = NULL;

  tt_int_op(buf_get_total_allocation(), OP_LT, 4008000);
  tt_int_op(buf_get_total_allocation(), OP_EQ, buf_allocation(buf1));
  buf_free(buf1);
  buf1 = NULL;
  tt_int_op(buf_get_total_allocation(), OP_EQ, 0);

 done:
  buf_free(buf1);
  buf_free(buf2);
  tor_free(junk);
}
예제 #13
0
static void
test_buffer_time_tracking(void *arg)
{
  buf_t *buf=NULL, *buf2=NULL;
  struct timeval tv0;
  const time_t START = 1389288246;
  const uint32_t START_MSEC = (uint32_t) ((uint64_t)START * 1000);
  int i;
  char tmp[4096];
  (void)arg;

  crypto_rand(tmp, sizeof(tmp));

  tv0.tv_sec = START;
  tv0.tv_usec = 0;

  buf = buf_new_with_capacity(3000); /* rounds up to next power of 2. */
  tt_assert(buf);

  /* Empty buffer means the timestamp is 0. */
  tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC));
  tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+1000));

  tor_gettimeofday_cache_set(&tv0);
  write_to_buf("ABCDEFG", 7, buf);
  tt_int_op(1000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+1000));

  buf2 = buf_copy(buf);
  tt_assert(buf2);
  tt_int_op(1234, OP_EQ,
            buf_get_oldest_chunk_timestamp(buf2, START_MSEC+1234));

  /* Now add more bytes; enough to overflow the first chunk. */
  tv0.tv_usec += 123 * 1000;
  tor_gettimeofday_cache_set(&tv0);
  for (i = 0; i < 600; ++i)
    write_to_buf("ABCDEFG", 7, buf);
  tt_int_op(4207, OP_EQ, buf_datalen(buf));

  /* The oldest bytes are still in the front. */
  tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2000));

  /* Once those bytes are dropped, the chunk is still on the first
   * timestamp. */
  fetch_from_buf(tmp, 100, buf);
  tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2000));

  /* But once we discard the whole first chunk, we get the data in the second
   * chunk. */
  fetch_from_buf(tmp, 4000, buf);
  tt_int_op(107, OP_EQ, buf_datalen(buf));
  tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2123));

  /* This time we'll be grabbing a chunk from the freelist, and making sure
     its time gets updated */
  tv0.tv_sec += 5;
  tv0.tv_usec = 617*1000;
  tor_gettimeofday_cache_set(&tv0);
  for (i = 0; i < 600; ++i)
    write_to_buf("ABCDEFG", 7, buf);
  tt_int_op(4307, OP_EQ, buf_datalen(buf));

  tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2123));
  fetch_from_buf(tmp, 4000, buf);
  fetch_from_buf(tmp, 306, buf);
  tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+5617));
  tt_int_op(383, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+6000));

 done:
  buf_free(buf);
  buf_free(buf2);
}
예제 #14
0
static void
test_buffer_pullup(void *arg)
{
  buf_t *buf;
  char *stuff, *tmp;
  const char *cp;
  size_t sz;
  (void)arg;
  stuff = tor_malloc(16384);
  tmp = tor_malloc(16384);

  buf = buf_new_with_capacity(3000); /* rounds up to next power of 2. */

  tt_assert(buf);
  tt_int_op(buf_get_default_chunk_size(buf), OP_EQ, 4096);

  tt_int_op(buf_get_total_allocation(), OP_EQ, 0);

  /* There are a bunch of cases for pullup.  One is the trivial case. Let's
     mess around with an empty buffer. */
  buf_pullup(buf, 16);
  buf_get_first_chunk_data(buf, &cp, &sz);
  tt_ptr_op(cp, OP_EQ, NULL);
  tt_uint_op(sz, OP_EQ, 0);

  /* Let's make sure nothing got allocated */
  tt_int_op(buf_get_total_allocation(), OP_EQ, 0);

  /* Case 1: everything puts into the first chunk with some moving. */

  /* Let's add some data. */
  crypto_rand(stuff, 16384);
  write_to_buf(stuff, 3000, buf);
  write_to_buf(stuff+3000, 3000, buf);
  buf_get_first_chunk_data(buf, &cp, &sz);
  tt_ptr_op(cp, OP_NE, NULL);
  tt_int_op(sz, OP_LE, 4096);

  /* Make room for 3000 bytes in the first chunk, so that the pullup-move code
   * can get tested. */
  tt_int_op(fetch_from_buf(tmp, 3000, buf), OP_EQ, 3000);
  tt_mem_op(tmp,OP_EQ, stuff, 3000);
  buf_pullup(buf, 2048);
  assert_buf_ok(buf);
  buf_get_first_chunk_data(buf, &cp, &sz);
  tt_ptr_op(cp, OP_NE, NULL);
  tt_int_op(sz, OP_GE, 2048);
  tt_mem_op(cp,OP_EQ, stuff+3000, 2048);
  tt_int_op(3000, OP_EQ, buf_datalen(buf));
  tt_int_op(fetch_from_buf(tmp, 3000, buf), OP_EQ, 0);
  tt_mem_op(tmp,OP_EQ, stuff+3000, 2048);

  buf_free(buf);

  /* Now try the large-chunk case. */
  buf = buf_new_with_capacity(3000); /* rounds up to next power of 2. */
  write_to_buf(stuff, 4000, buf);
  write_to_buf(stuff+4000, 4000, buf);
  write_to_buf(stuff+8000, 4000, buf);
  write_to_buf(stuff+12000, 4000, buf);
  tt_int_op(buf_datalen(buf), OP_EQ, 16000);
  buf_get_first_chunk_data(buf, &cp, &sz);
  tt_ptr_op(cp, OP_NE, NULL);
  tt_int_op(sz, OP_LE, 4096);

  buf_pullup(buf, 12500);
  assert_buf_ok(buf);
  buf_get_first_chunk_data(buf, &cp, &sz);
  tt_ptr_op(cp, OP_NE, NULL);
  tt_int_op(sz, OP_GE, 12500);
  tt_mem_op(cp,OP_EQ, stuff, 12500);
  tt_int_op(buf_datalen(buf), OP_EQ, 16000);

  fetch_from_buf(tmp, 12400, buf);
  tt_mem_op(tmp,OP_EQ, stuff, 12400);
  tt_int_op(buf_datalen(buf), OP_EQ, 3600);
  fetch_from_buf(tmp, 3500, buf);
  tt_mem_op(tmp,OP_EQ, stuff+12400, 3500);
  fetch_from_buf(tmp, 100, buf);
  tt_mem_op(tmp,OP_EQ, stuff+15900, 10);

  buf_free(buf);

  /* Make sure that the pull-up-whole-buffer case works */
  buf = buf_new_with_capacity(3000); /* rounds up to next power of 2. */
  write_to_buf(stuff, 4000, buf);
  write_to_buf(stuff+4000, 4000, buf);
  fetch_from_buf(tmp, 100, buf); /* dump 100 bytes from first chunk */
  buf_pullup(buf, 16000); /* Way too much. */
  assert_buf_ok(buf);
  buf_get_first_chunk_data(buf, &cp, &sz);
  tt_ptr_op(cp, OP_NE, NULL);
  tt_int_op(sz, OP_EQ, 7900);
  tt_mem_op(cp,OP_EQ, stuff+100, 7900);

  buf_free(buf);
  buf = NULL;

  tt_int_op(buf_get_total_allocation(), OP_EQ, 0);
 done:
  buf_free(buf);
  tor_free(stuff);
  tor_free(tmp);
}
예제 #15
0
/** Run unit tests for buffers.c */
static void
test_buffers_basic(void *arg)
{
  char str[256];
  char str2[256];

  buf_t *buf = NULL, *buf2 = NULL;
  const char *cp;

  int j;
  size_t r;
  (void) arg;

  /****
   * buf_new
   ****/
  if (!(buf = buf_new()))
    TT_DIE(("Assertion failed."));

  //test_eq(buf_capacity(buf), 4096);
  tt_int_op(buf_datalen(buf),OP_EQ, 0);

  /****
   * General pointer frobbing
   */
  for (j=0;j<256;++j) {
    str[j] = (char)j;
  }
  write_to_buf(str, 256, buf);
  write_to_buf(str, 256, buf);
  tt_int_op(buf_datalen(buf),OP_EQ, 512);
  fetch_from_buf(str2, 200, buf);
  tt_mem_op(str,OP_EQ, str2, 200);
  tt_int_op(buf_datalen(buf),OP_EQ, 312);
  memset(str2, 0, sizeof(str2));

  fetch_from_buf(str2, 256, buf);
  tt_mem_op(str+200,OP_EQ, str2, 56);
  tt_mem_op(str,OP_EQ, str2+56, 200);
  tt_int_op(buf_datalen(buf),OP_EQ, 56);
  memset(str2, 0, sizeof(str2));
  /* Okay, now we should be 512 bytes into the 4096-byte buffer.  If we add
   * another 3584 bytes, we hit the end. */
  for (j=0;j<15;++j) {
    write_to_buf(str, 256, buf);
  }
  assert_buf_ok(buf);
  tt_int_op(buf_datalen(buf),OP_EQ, 3896);
  fetch_from_buf(str2, 56, buf);
  tt_int_op(buf_datalen(buf),OP_EQ, 3840);
  tt_mem_op(str+200,OP_EQ, str2, 56);
  for (j=0;j<15;++j) {
    memset(str2, 0, sizeof(str2));
    fetch_from_buf(str2, 256, buf);
    tt_mem_op(str,OP_EQ, str2, 256);
  }
  tt_int_op(buf_datalen(buf),OP_EQ, 0);
  buf_free(buf);
  buf = NULL;

  /* Okay, now make sure growing can work. */
  buf = buf_new_with_capacity(16);
  //test_eq(buf_capacity(buf), 16);
  write_to_buf(str+1, 255, buf);
  //test_eq(buf_capacity(buf), 256);
  fetch_from_buf(str2, 254, buf);
  tt_mem_op(str+1,OP_EQ, str2, 254);
  //test_eq(buf_capacity(buf), 256);
  assert_buf_ok(buf);
  write_to_buf(str, 32, buf);
  //test_eq(buf_capacity(buf), 256);
  assert_buf_ok(buf);
  write_to_buf(str, 256, buf);
  assert_buf_ok(buf);
  //test_eq(buf_capacity(buf), 512);
  tt_int_op(buf_datalen(buf),OP_EQ, 33+256);
  fetch_from_buf(str2, 33, buf);
  tt_int_op(*str2,OP_EQ, str[255]);

  tt_mem_op(str2+1,OP_EQ, str, 32);
  //test_eq(buf_capacity(buf), 512);
  tt_int_op(buf_datalen(buf),OP_EQ, 256);
  fetch_from_buf(str2, 256, buf);
  tt_mem_op(str,OP_EQ, str2, 256);

  /* now try shrinking: case 1. */
  buf_free(buf);
  buf = buf_new_with_capacity(33668);
  for (j=0;j<67;++j) {
    write_to_buf(str,255, buf);
  }
  //test_eq(buf_capacity(buf), 33668);
  tt_int_op(buf_datalen(buf),OP_EQ, 17085);
  for (j=0; j < 40; ++j) {
    fetch_from_buf(str2, 255,buf);
    tt_mem_op(str2,OP_EQ, str, 255);
  }

  /* now try shrinking: case 2. */
  buf_free(buf);
  buf = buf_new_with_capacity(33668);
  for (j=0;j<67;++j) {
    write_to_buf(str,255, buf);
  }
  for (j=0; j < 20; ++j) {
    fetch_from_buf(str2, 255,buf);
    tt_mem_op(str2,OP_EQ, str, 255);
  }
  for (j=0;j<80;++j) {
    write_to_buf(str,255, buf);
  }
  //test_eq(buf_capacity(buf),33668);
  for (j=0; j < 120; ++j) {
    fetch_from_buf(str2, 255,buf);
    tt_mem_op(str2,OP_EQ, str, 255);
  }

  /* Move from buf to buf. */
  buf_free(buf);
  buf = buf_new_with_capacity(4096);
  buf2 = buf_new_with_capacity(4096);
  for (j=0;j<100;++j)
    write_to_buf(str, 255, buf);
  tt_int_op(buf_datalen(buf),OP_EQ, 25500);
  for (j=0;j<100;++j) {
    r = 10;
    move_buf_to_buf(buf2, buf, &r);
    tt_int_op(r,OP_EQ, 0);
  }
  tt_int_op(buf_datalen(buf),OP_EQ, 24500);
  tt_int_op(buf_datalen(buf2),OP_EQ, 1000);
  for (j=0;j<3;++j) {
    fetch_from_buf(str2, 255, buf2);
    tt_mem_op(str2,OP_EQ, str, 255);
  }
  r = 8192; /*big move*/
  move_buf_to_buf(buf2, buf, &r);
  tt_int_op(r,OP_EQ, 0);
  r = 30000; /* incomplete move */
  move_buf_to_buf(buf2, buf, &r);
  tt_int_op(r,OP_EQ, 13692);
  for (j=0;j<97;++j) {
    fetch_from_buf(str2, 255, buf2);
    tt_mem_op(str2,OP_EQ, str, 255);
  }
  buf_free(buf);
  buf_free(buf2);
  buf = buf2 = NULL;

  buf = buf_new_with_capacity(5);
  cp = "Testing. This is a moderately long Testing string.";
  for (j = 0; cp[j]; j++)
    write_to_buf(cp+j, 1, buf);
  tt_int_op(0,OP_EQ, buf_find_string_offset(buf, "Testing", 7));
  tt_int_op(1,OP_EQ, buf_find_string_offset(buf, "esting", 6));
  tt_int_op(1,OP_EQ, buf_find_string_offset(buf, "est", 3));
  tt_int_op(39,OP_EQ, buf_find_string_offset(buf, "ing str", 7));
  tt_int_op(35,OP_EQ, buf_find_string_offset(buf, "Testing str", 11));
  tt_int_op(32,OP_EQ, buf_find_string_offset(buf, "ng ", 3));
  tt_int_op(43,OP_EQ, buf_find_string_offset(buf, "string.", 7));
  tt_int_op(-1,OP_EQ, buf_find_string_offset(buf, "shrdlu", 6));
  tt_int_op(-1,OP_EQ, buf_find_string_offset(buf, "Testing thing", 13));
  tt_int_op(-1,OP_EQ, buf_find_string_offset(buf, "ngx", 3));
  buf_free(buf);
  buf = NULL;

  /* Try adding a string too long for any freelist. */
  {
    char *cp = tor_malloc_zero(65536);
    buf = buf_new();
    write_to_buf(cp, 65536, buf);
    tor_free(cp);

    tt_int_op(buf_datalen(buf), OP_EQ, 65536);
    buf_free(buf);
    buf = NULL;
  }

 done:
  if (buf)
    buf_free(buf);
  if (buf2)
    buf_free(buf2);
}
예제 #16
0
static void write_response_error(struct fd_state *state) {
    const char* msg = "HTTP/1.1 404 Not Found\r\nContent-Length:0\r\n\r\n";
    write_to_buf(state, msg, strlen(msg));
}
예제 #17
0
파일: test_buffers.c 프로젝트: adoll/tor
static void
test_buffer_allocation_tracking(void *arg)
{
  char *junk = tor_malloc(16384);
  buf_t *buf1 = NULL, *buf2 = NULL;
  int i;

  (void)arg;

  crypto_rand(junk, 16384);
  tt_int_op(buf_get_total_allocation(), OP_EQ, 0);

  buf1 = buf_new();
  tt_assert(buf1);
  buf2 = buf_new();
  tt_assert(buf2);

  tt_int_op(buf_allocation(buf1), OP_EQ, 0);
  tt_int_op(buf_get_total_allocation(), OP_EQ, 0);

  write_to_buf(junk, 4000, buf1);
  write_to_buf(junk, 4000, buf1);
  write_to_buf(junk, 4000, buf1);
  write_to_buf(junk, 4000, buf1);
  tt_int_op(buf_allocation(buf1), OP_EQ, 16384);
  fetch_from_buf(junk, 100, buf1);
  tt_int_op(buf_allocation(buf1), OP_EQ, 16384); /* still 4 4k chunks */

  tt_int_op(buf_get_total_allocation(), OP_EQ, 16384);

  fetch_from_buf(junk, 4096, buf1); /* drop a 1k chunk... */
  tt_int_op(buf_allocation(buf1), OP_EQ, 3*4096); /* now 3 4k chunks */

#ifdef ENABLE_BUF_FREELISTS
  tt_int_op(buf_get_total_allocation(), OP_EQ, 16384); /* that chunk went onto
                                                       the freelist. */
#else
  tt_int_op(buf_get_total_allocation(), OP_EQ, 12288); /* that chunk was really
                                                       freed. */
#endif

  write_to_buf(junk, 4000, buf2);
  tt_int_op(buf_allocation(buf2), OP_EQ, 4096); /* another 4k chunk. */
  /*
   * If we're using freelists, size stays at 16384 because we just pulled a
   * chunk from the freelist.  If we aren't, we bounce back up to 16384 by
   * allocating a new chunk.
   */
  tt_int_op(buf_get_total_allocation(), OP_EQ, 16384);
  write_to_buf(junk, 4000, buf2);
  tt_int_op(buf_allocation(buf2), OP_EQ, 8192); /* another 4k chunk. */
  tt_int_op(buf_get_total_allocation(),
            OP_EQ, 5*4096); /* that chunk was new. */

  /* Make a really huge buffer */
  for (i = 0; i < 1000; ++i) {
    write_to_buf(junk, 4000, buf2);
  }
  tt_int_op(buf_allocation(buf2), OP_GE, 4008000);
  tt_int_op(buf_get_total_allocation(), OP_GE, 4008000);
  buf_free(buf2);
  buf2 = NULL;

  tt_int_op(buf_get_total_allocation(), OP_LT, 4008000);
  buf_shrink_freelists(1);
  tt_int_op(buf_get_total_allocation(), OP_EQ, buf_allocation(buf1));
  buf_free(buf1);
  buf1 = NULL;
  buf_shrink_freelists(1);
  tt_int_op(buf_get_total_allocation(), OP_EQ, 0);

 done:
  buf_free(buf1);
  buf_free(buf2);
  buf_shrink_freelists(1);
  tor_free(junk);
}
예제 #18
0
static void
test_buffer_copy(void *arg)
{
    buf_t *buf=NULL, *buf2=NULL;
    const char *s;
    size_t len;
    char b[256];
    int i;
    (void)arg;

    buf = buf_new();
    tt_assert(buf);

    /* Copy an empty buffer. */
    tt_int_op(0, OP_EQ, buf_set_to_copy(&buf2, buf));
    tt_assert(buf2);
    tt_int_op(0, OP_EQ, buf_datalen(buf2));

    /* Now try with a short buffer. */
    s = "And now comes an act of enormous enormance!";
    len = strlen(s);
    write_to_buf(s, len, buf);
    tt_int_op(len, OP_EQ, buf_datalen(buf));
    /* Add junk to buf2 so we can test replacing.*/
    write_to_buf("BLARG", 5, buf2);
    tt_int_op(0, OP_EQ, buf_set_to_copy(&buf2, buf));
    tt_int_op(len, OP_EQ, buf_datalen(buf2));
    fetch_from_buf(b, len, buf2);
    tt_mem_op(b, OP_EQ, s, len);
    /* Now free buf2 and retry so we can test allocating */
    buf_free(buf2);
    buf2 = NULL;
    tt_int_op(0, OP_EQ, buf_set_to_copy(&buf2, buf));
    tt_int_op(len, OP_EQ, buf_datalen(buf2));
    fetch_from_buf(b, len, buf2);
    tt_mem_op(b, OP_EQ, s, len);
    /* Clear buf for next test */
    fetch_from_buf(b, len, buf);
    tt_int_op(buf_datalen(buf),OP_EQ,0);

    /* Okay, now let's try a bigger buffer. */
    s = "Quis autem vel eum iure reprehenderit qui in ea voluptate velit "
        "esse quam nihil molestiae consequatur, vel illum qui dolorem eum "
        "fugiat quo voluptas nulla pariatur?";
    len = strlen(s);
    for (i = 0; i < 256; ++i) {
        b[0]=i;
        write_to_buf(b, 1, buf);
        write_to_buf(s, len, buf);
    }
    tt_int_op(0, OP_EQ, buf_set_to_copy(&buf2, buf));
    tt_int_op(buf_datalen(buf2), OP_EQ, buf_datalen(buf));
    for (i = 0; i < 256; ++i) {
        fetch_from_buf(b, len+1, buf2);
        tt_int_op((unsigned char)b[0],OP_EQ,i);
        tt_mem_op(b+1, OP_EQ, s, len);
    }

done:
    if (buf)
        buf_free(buf);
    if (buf2)
        buf_free(buf2);
}