Example #1
0
/**
 * Create a memory pool.
 * @param size Size of each memory block. Use default value if 0.
 * @return A pointer to created pool, NULL on error.
 */
pool_t *pool_create(size_t size)
{
	if (!_max_pool_alloc)
		_max_pool_alloc = sysconf(_SC_PAGESIZE);

	if (!size)
		size = _max_pool_alloc * 2;

	if (size <= sizeof(pool_block_t))
		return NULL;

	pool_block_t *b = malloc(size);
	if (!b)
		return NULL;

	b->last = _align_ptr((uchar_t *)b + sizeof(*b));
	b->end = (uchar_t *)b + size;
	b->next = NULL;

	pool_t *p = (pool_t *) b->last;
	b->last = (uchar_t *)p + sizeof(*p);
	p->head = b;
	p->large = NULL;

	return p;
}
Example #2
0
/**
 * Clear memory pool.
 * Large memories are freed. Blocks are cleared.
 * @param p The memory pool.
 */
void pool_clear(pool_t *p)
{
	for (pool_large_t *l = p->large; l; l = l->next) {
		if (l->ptr)
			free(l->ptr);
	}
	p->large = NULL;

	for (pool_block_t *b = p->head->next; b; b = b->next) {
		b->last = (uchar_t *)b + sizeof(*b);
	}
	p->head->last = _align_ptr((uchar_t *)(p->head) + sizeof(pool_block_t));
	p->head->last += sizeof(*p);
}
Example #3
0
/**
 * Allocate memory from pool by creating a new block.
 * @param p The pool to allocate from.
 * @param size Required memory size.
 * @return On success, a pointer to allocated space, NULL otherwise.
 */
static void *_pool_alloc_block(pool_t *p, size_t size)
{
	size_t bsize = p->head->end - (uchar_t *)(p->head);
	pool_block_t *b = malloc(bsize);
	if (!b)
		return NULL;

	b->last = (uchar_t *)b + sizeof(*b);
	b->end = (uchar_t *)b + bsize;
	b->next = p->head->next;
	p->head->next = b;

	uchar_t *ret = _align_ptr(b->last);
	b->last = ret + size;
	return ret;
}
Example #4
0
/**
 * Allocate memory from pool.
 * @param p The pool to allocate from.
 * @param size Required memory size.
 * @return On success, a pointer to allocated space, NULL otherwise.
 */
void *pool_alloc(pool_t *p, size_t size)
{
	uchar_t *ret;
	pool_block_t *b;
	if (size < _max_pool_alloc) {
		b = p->head;
		do {
			ret = _align_ptr(b->last);
			if (b->end - ret >= size) {
				b->last = (uchar_t *)ret + size;
				return ret;
			}
			b = b->next;
		} while (b);
		return _pool_alloc_block(p, size);
	}
	return _pool_alloc_large(p, size);
}
Example #5
0
/**
 * Parses an SPF macro string.
 *
 * Note that we cannot write data_avail bytes from data, since we
 * might be called with a modified data pointer. We MUST compare
 * data_used with data_avail.
 *
 * @param spf_server The SPF server on whose behalf the record is being compiled.
 * @param spf_response The SPF response in which to store errors.
 * @param data Output buffer pointer.
 * @param data_used Output parameter for amount of data written to output buffer.
 * @param data_avail Input parameter for size of output buffer.
 * @param src Input buffer pointer.
 * @param src_len Input buffer length.
 * @param big_err The error code to return on an over-length condition.
 * @param is_mod True if this is a modifier.
 */
static SPF_errcode_t
SPF_c_parse_macro(SPF_server_t *spf_server,
				SPF_response_t *spf_response,
				SPF_data_t *data, size_t *data_used, size_t data_avail,
				const char *src, size_t src_len,
				SPF_errcode_t big_err,
				int is_mod)
{
	SPF_errcode_t		 err;
			/* Generic parsing iterators and boundaries */
	size_t				 idx;
	size_t				 len;
			/* For parsing strings. */
	char				*dst;
	size_t				 ds_avail;
	size_t				 ds_len;

	if (spf_server->debug)
		SPF_debugf("Parsing macro starting at %s", src);

#if 0
	if ((void *)data != _align_ptr((void *)data))
		SPF_errorf("Data pointer %p is not aligned: Cannot compile.",
		data);
#endif

	/*
	 * Create the data blocks
	 */
	idx = 0;

	/* Initialise the block as a string. If ds_len == 0 later, we
	 * will just clobber it. */
	SPF_INIT_STRING_LITERAL(data_avail - *data_used);

	// while ( p != end ) {
	while (idx < src_len) {
		if (spf_server->debug > 3)
			SPF_debugf("Current data is at %p", data);
		/* Either the unit is terminated by a space, or we hit a %.
		 * We should only hit a space if we run past src_len. */
		len = strcspn(&src[idx], " %");	// XXX Also tab?
		if (len > 0) {				/* An optimisation */
			/* Don't over-run into the CIDR. */
			if (idx + len > src_len)
				len = src_len - idx;
			if (spf_server->debug > 3)
				SPF_debugf("Adding string literal (%lu): '%*.*s'",
								(unsigned long)len,
								(int)len, (int)len, &src[idx]);
			/* XXX Bounds-check here. */
			SPF_ENSURE_STRING_AVAIL(len);
			memcpy(dst, &src[idx], len);
			ds_len += len;
			dst += len;
			idx += len;

			/* If len == 0 then we never entered the while(). Thus
			 * if idx == src_len, then len != 0 and we reach this test.
			 */
		}
		/* However, this logic is overcomplex and I am a simpleton,
		 * so I have moved it out of the condition above. */
		if (idx == src_len)
			break;

		/* Now, we must have a %-escape code, since if we hit a
		 * space, then we are at the end.
		 * Incrementing idx consumes the % we hit first, and then
		 * we switch on the following character, which also
		 * increments idx. */
		idx++;
		switch (src[idx]) {
		case '%':
			if (spf_server->debug > 3)
				SPF_debugf("Adding literal %%");
			SPF_ENSURE_STRING_AVAIL(1);
			*dst++ = '%';
			ds_len++;
			idx++;
			break;
			
		case '_':
			if (spf_server->debug > 3)
				SPF_debugf("Adding literal space");
			SPF_ENSURE_STRING_AVAIL(1);
			*dst++ = ' ';
			ds_len++;
			idx++;
			break;

		case '-':
			if (spf_server->debug > 3)
				SPF_debugf("Adding escaped space");
			SPF_ENSURE_STRING_AVAIL(3);
			*dst++ = '%'; *dst++ = '2'; *dst++ = '0';
			ds_len += 3;
			idx++;
			break;

		default:
			if (spf_server->debug > 3)
				SPF_debugf("Adding illegal %%-follower '%c' at %d",
				src[idx], idx);
			/* SPF spec says to treat it as a literal, not
			 * SPF_E_INVALID_ESC */
			/* FIXME   issue a warning? */
			SPF_ENSURE_STRING_AVAIL(1);
			*dst++ = '%';
			ds_len++;
			break;

		case '{':  /*vi:}*/
			SPF_FINI_STRING_LITERAL();
			if (spf_server->debug > 3)
				SPF_debugf("Adding macro, data is at %p", data);

			/* this must be a variable */
			idx++;
			err = SPF_c_parse_var(spf_response, &data->dv, &src[idx], is_mod);
			if (err != SPF_E_SUCCESS)
				return err;
			idx += strcspn(&src[idx], "} ");
			if (src[idx] == '}')
				idx++;
			else if (src[idx] == ' ')
				return SPF_response_add_error_ptr(spf_response,
						SPF_E_INVALID_VAR,
						src, &src[idx],
						"Unterminated variable?");


			len = SPF_data_len(data);
			SPF_ADD_LEN_TO(*data_used, len, data_avail);
			data = SPF_data_next( data );
			if (spf_server->debug > 3)
				SPF_debugf("Next data is at %p", data);

			SPF_INIT_STRING_LITERAL(data_avail - *data_used);

			break;
		}
	}

	SPF_FINI_STRING_LITERAL();

	return SPF_E_SUCCESS;

}