allocate buffer and data in a single allocation

--HG--
branch : nocircbuffer
This commit is contained in:
Matt Johnston 2015-03-01 21:16:09 +08:00
parent 91ef9b2fa9
commit f367273549
4 changed files with 40 additions and 49 deletions

View File

@ -46,17 +46,15 @@ buffer* buf_new(unsigned int size) {
dropbear_exit("buf->size too big"); dropbear_exit("buf->size too big");
} }
buf = (buffer*)m_malloc(sizeof(buffer)); buf = (buffer*)m_malloc(sizeof(buffer)+size);
if (size > 0) { if (size > 0) {
buf->data = (unsigned char*)m_malloc(size); buf->data = (unsigned char*)buf + sizeof(buffer);
} else { } else {
buf->data = NULL; buf->data = NULL;
} }
buf->size = size; buf->size = size;
buf->pos = 0;
buf->len = 0;
return buf; return buf;
@ -65,7 +63,6 @@ buffer* buf_new(unsigned int size) {
/* free the buffer's data and the buffer itself */ /* free the buffer's data and the buffer itself */
void buf_free(buffer* buf) { void buf_free(buffer* buf) {
m_free(buf->data)
m_free(buf); m_free(buf);
} }
@ -78,17 +75,18 @@ void buf_burn(buffer* buf) {
/* resize a buffer, pos and len will be repositioned if required when /* resize a buffer, pos and len will be repositioned if required when
* downsizing */ * downsizing */
void buf_resize(buffer *buf, unsigned int newsize) { buffer* buf_resize(buffer *buf, unsigned int newsize) {
if (newsize > BUF_MAX_SIZE) { if (newsize > BUF_MAX_SIZE) {
dropbear_exit("buf->size too big"); dropbear_exit("buf->size too big");
} }
buf->data = m_realloc(buf->data, newsize); buf = m_realloc(buf, sizeof(buffer)+newsize);
buf->data = (unsigned char*)buf + sizeof(buffer);
buf->size = newsize; buf->size = newsize;
buf->len = MIN(newsize, buf->len); buf->len = MIN(newsize, buf->len);
buf->pos = MIN(newsize, buf->pos); buf->pos = MIN(newsize, buf->pos);
return buf;
} }
/* Create a copy of buf, allocating required memory etc. */ /* Create a copy of buf, allocating required memory etc. */
@ -227,15 +225,15 @@ unsigned char* buf_getstring(buffer* buf, unsigned int *retlen) {
/* Return a string as a newly allocated buffer */ /* Return a string as a newly allocated buffer */
buffer * buf_getstringbuf(buffer *buf) { buffer * buf_getstringbuf(buffer *buf) {
buffer *ret; buffer *ret = NULL;
unsigned char* str; unsigned int len = buf_getint(buf);
unsigned int len; if (len > MAX_STRING_LEN) {
str = buf_getstring(buf, &len); dropbear_exit("String too long");
ret = m_malloc(sizeof(*ret)); }
ret->data = str; ret = buf_new(len);
ret->len = len; memcpy(buf_getwriteptr(ret, len), buf_getptr(buf, len), len);
ret->size = len; buf_incrpos(buf, len);
ret->pos = 0; buf_incrlen(ret, len);
return ret; return ret;
} }

View File

@ -29,7 +29,8 @@
#include "includes.h" #include "includes.h"
struct buf { struct buf {
/* don't manipulate data member outside of buffer.c - it
is a pointer into the malloc holding buffer itself */
unsigned char * data; unsigned char * data;
unsigned int len; /* the used size */ unsigned int len; /* the used size */
unsigned int pos; unsigned int pos;
@ -40,7 +41,8 @@ struct buf {
typedef struct buf buffer; typedef struct buf buffer;
buffer * buf_new(unsigned int size); buffer * buf_new(unsigned int size);
void buf_resize(buffer *buf, unsigned int newsize); /* Possibly returns a new buffer*, like realloc() */
buffer * buf_resize(buffer *buf, unsigned int newsize);
void buf_free(buffer* buf); void buf_free(buffer* buf);
void buf_burn(buffer* buf); void buf_burn(buffer* buf);
buffer* buf_newcopy(buffer* buf); buffer* buf_newcopy(buffer* buf);

View File

@ -155,7 +155,7 @@ static buffer * agent_request(unsigned char type, buffer *data) {
goto out; goto out;
} }
buf_resize(inbuf, readlen); inbuf = buf_resize(inbuf, readlen);
buf_setpos(inbuf, 0); buf_setpos(inbuf, 0);
ret = atomicio(read, fd, buf_getwriteptr(inbuf, readlen), readlen); ret = atomicio(read, fd, buf_getwriteptr(inbuf, readlen), readlen);
if ((size_t)ret != readlen) { if ((size_t)ret != readlen) {

View File

@ -257,7 +257,7 @@ static int read_packet_init() {
} }
if (len > ses.readbuf->size) { if (len > ses.readbuf->size) {
buf_resize(ses.readbuf, len); ses.readbuf = buf_resize(ses.readbuf, len);
} }
buf_setlen(ses.readbuf, len); buf_setlen(ses.readbuf, len);
buf_setpos(ses.readbuf, blocksize); buf_setpos(ses.readbuf, blocksize);
@ -401,7 +401,7 @@ static buffer* buf_decompress(buffer* buf, unsigned int len) {
dropbear_exit("bad packet, oversized decompressed"); dropbear_exit("bad packet, oversized decompressed");
} }
new_size = MIN(RECV_MAX_PAYLOAD_LEN, ret->size + ZLIB_DECOMPRESS_INCR); new_size = MIN(RECV_MAX_PAYLOAD_LEN, ret->size + ZLIB_DECOMPRESS_INCR);
buf_resize(ret, new_size); ret = buf_resize(ret, new_size);
} }
} }
} }
@ -640,7 +640,8 @@ static void make_mac(unsigned int seqno, const struct key_context_directional *
#ifndef DISABLE_ZLIB #ifndef DISABLE_ZLIB
/* compresses len bytes from src, outputting to dest (starting from the /* compresses len bytes from src, outputting to dest (starting from the
* respective current positions. */ * respective current positions. dest must have sufficient space,
* len+ZLIB_COMPRESS_EXPANSION */
static void buf_compress(buffer * dest, buffer * src, unsigned int len) { static void buf_compress(buffer * dest, buffer * src, unsigned int len) {
unsigned int endpos = src->pos + len; unsigned int endpos = src->pos + len;
@ -648,7 +649,7 @@ static void buf_compress(buffer * dest, buffer * src, unsigned int len) {
TRACE2(("enter buf_compress")) TRACE2(("enter buf_compress"))
while (1) { dropbear_assert(dest->size - dest->pos >= len+ZLIB_COMPRESS_EXPANSION);
ses.keys->trans.zstream->avail_in = endpos - src->pos; ses.keys->trans.zstream->avail_in = endpos - src->pos;
ses.keys->trans.zstream->next_in = ses.keys->trans.zstream->next_in =
@ -668,18 +669,8 @@ static void buf_compress(buffer * dest, buffer * src, unsigned int len) {
dropbear_exit("zlib error"); dropbear_exit("zlib error");
} }
if (ses.keys->trans.zstream->avail_in == 0) { /* fails if destination buffer wasn't large enough */
break; dropbear_assert(ses.keys->trans.zstream->avail_in == 0);
}
dropbear_assert(ses.keys->trans.zstream->avail_out == 0);
/* the buffer has been filled, we must extend. This only happens in
* unusual circumstances where the data grows in size after deflate(),
* but it is possible */
buf_resize(dest, dest->size + ZLIB_COMPRESS_EXPANSION);
}
TRACE2(("leave buf_compress")) TRACE2(("leave buf_compress"))
} }
#endif #endif