A few bugfixes to prepend_size and append_size so they don't create unnecessary empty nodes. Minor cleanup to ipv4.cpp.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18951 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Andrew Galante
2006-09-27 18:56:06 +00:00
parent 646182be71
commit 0054baf8c9
2 changed files with 76 additions and 42 deletions
@@ -484,8 +484,6 @@ dump_ipv4_header(ipv4_header &header)
\return B_OK if everything went well; if it could reassemble the packet, \a _buffer \return B_OK if everything went well; if it could reassemble the packet, \a _buffer
will point to its buffer, otherwise, it will be \c NULL. will point to its buffer, otherwise, it will be \c NULL.
\return various error codes if something went wrong (mostly B_NO_MEMORY) \return various error codes if something went wrong (mostly B_NO_MEMORY)
TODO: Implement packet aging
*/ */
static status_t static status_t
reassemble_fragments(const ipv4_header &header, net_buffer **_buffer) reassemble_fragments(const ipv4_header &header, net_buffer **_buffer)
+76 -40
View File
@@ -486,27 +486,39 @@ net_buffer_read_data(net_buffer *_buffer, size_t offset, void *data, size_t size
static data_node * static data_node *
data_node_prepend_size(data_node *node, size_t size, void **_contiguousBuffer) data_node_prepend_size(data_node *node, size_t size, void **_contiguousBuffer)
{ {
if (node->header_space < size) { if (node->header_space < size) {
// need one or more new buffers data_node *new_node;
data_node *new_node = (data_node *)malloc(sizeof(data_node)); size_t available_space;
new_node->datablock = (uint8 *)get_datablock(&sDatastore); if (node->size == 0) {
if (new_node->datablock == NULL) { // current node is empty; use it before making new ones
free(new_node); available_space = node->header_space + node->trailer_space;
return NULL; node->start += node->trailer_space;
} new_node = node;
node->previous = new_node;
new_node->next = node;
new_node->previous = NULL;
new_node->trailer_space = 0;
if (size > BUFFER_SIZE) {
new_node->header_space = 0;
new_node->start = new_node->datablock;
new_node->size = BUFFER_SIZE;
*_contiguousBuffer = NULL;
return data_node_prepend_size(new_node, size - BUFFER_SIZE, NULL);
} else { } else {
new_node->header_space = BUFFER_SIZE - size; // need one or more new nodes
new_node->start = new_node->datablock + new_node->header_space; new_node = (data_node *)malloc(sizeof(data_node));
new_node->datablock = (uint8 *)get_datablock(&sDatastore);
if (new_node->datablock == NULL) {
free(new_node);
return NULL;
}
available_space = BUFFER_SIZE;
node->previous = new_node;
new_node->next = node;
new_node->previous = NULL;
new_node->start = node->datablock + available_space;
}
new_node->trailer_space = 0;
if (size > available_space) {
new_node->header_space = 0;
new_node->size = available_space;
new_node->start -= available_space;
*_contiguousBuffer = NULL;
return data_node_prepend_size(new_node, size - available_space, NULL);
} else {
new_node->header_space = available_space - size;
new_node->start -= size;
new_node->size = size; new_node->size = size;
if (_contiguousBuffer != NULL) if (_contiguousBuffer != NULL)
*_contiguousBuffer = new_node->start; *_contiguousBuffer = new_node->start;
@@ -571,25 +583,35 @@ data_node_append_size(data_node *node, size_t size, void **_contiguousBuffer)
node = node->next; node = node->next;
if (node->trailer_space < size) { if (node->trailer_space < size) {
// need one or more new buffers data_node *new_node;
data_node *new_node = (data_node *)malloc(sizeof(data_node)); size_t available_space;
new_node->datablock = (uint8 *)get_datablock(&sDatastore); if (node->size == 0) {
if (new_node->datablock == NULL) { // if this node is empty, use it before making new nodes
free(new_node); available_space = node->header_space + node->trailer_space;
return ENOBUFS; node->start -= node->header_space;
} new_node = node;
new_node->previous = node;
node->next = new_node;
new_node->next = NULL;
new_node->header_space = 0;
new_node->start = new_node->datablock;
if (size > BUFFER_SIZE) {
new_node->trailer_space = 0;
new_node->size = BUFFER_SIZE;
*_contiguousBuffer = NULL;
return data_node_append_size(new_node, size - BUFFER_SIZE, NULL);
} else { } else {
new_node->trailer_space = BUFFER_SIZE - size; // need one or more new buffers
new_node = (data_node *)malloc(sizeof(data_node));
new_node->datablock = (uint8 *)get_datablock(&sDatastore);
if (new_node->datablock == NULL) {
free(new_node);
return ENOBUFS;
}
available_space = BUFFER_SIZE;
new_node->previous = node;
node->next = new_node;
new_node->next = NULL;
new_node->start = new_node->datablock;
}
new_node->header_space = 0;
if (size > available_space) {
new_node->trailer_space = 0;
new_node->size = available_space;
*_contiguousBuffer = NULL;
return data_node_append_size(new_node, size - available_space, NULL);
} else {
new_node->trailer_space = available_space - size;
new_node->size = size; new_node->size = size;
if (_contiguousBuffer != NULL) if (_contiguousBuffer != NULL)
*_contiguousBuffer = new_node->start; *_contiguousBuffer = new_node->start;
@@ -701,9 +723,10 @@ data_node_trim_data(data_node *node, size_t newSize)
} else { } else {
node->trailer_space += node->size - newSize; node->trailer_space += node->size - newSize;
node->size = newSize; node->size = newSize;
if (node->next != NULL) if (node->next != NULL) {
data_node_free(node->next); data_node_free(node->next);
node->next = NULL; node->next = NULL;
}
} }
} }
return B_OK; return B_OK;
@@ -731,6 +754,19 @@ net_buffer_trim_data(net_buffer *_buffer, size_t newSize)
} }
/*!
* Removes \a bytes from the end of \a buffer
*/
static status_t
net_buffer_remove_trailer(net_buffer *buffer, size_t bytes)
{
if (buffer->size < bytes)
return B_BAD_VALUE;
return net_buffer_trim_data(buffer, buffer->size - bytes);
}
/*! /*!
Tries to directly access the requested space in the buffer. Tries to directly access the requested space in the buffer.
If the space is contiguous, the function will succeed and place a pointer If the space is contiguous, the function will succeed and place a pointer
@@ -896,7 +932,7 @@ net_buffer_module_info gNetBufferModule = {
NULL, // net_buffer_insert NULL, // net_buffer_insert
NULL, // net_buffer_remove NULL, // net_buffer_remove
net_buffer_remove_header, net_buffer_remove_header,
net_buffer_trim_data, // net_buffer_remove_trailer net_buffer_remove_trailer,
net_buffer_trim_data, net_buffer_trim_data,
NULL, // net_buffer_associate_data NULL, // net_buffer_associate_data