Fixed several problems:

* sockaddr_storage::ss_len is max 255, but the structure itself is shorter; we must
  not copy ss_len bytes without checking the length first (duplicate & clone were affected).
* count_iovecs() & get_iovecs() both did not work with empty buffers that don't
  have any nodes at all (unlikely case, but should be supported).
* the net_buffer::offset union field was not copied in clone & duplicate.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19555 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-12-18 19:13:59 +00:00
parent 85895023b3
commit c0d50aaedb
+16 -12
View File
@@ -321,11 +321,14 @@ duplicate_buffer(net_buffer *_buffer)
// copy meta data from source buffer // copy meta data from source buffer
memcpy(&duplicate->source, &buffer->source, buffer->source.ss_len); memcpy(&duplicate->source, &buffer->source,
memcpy(&duplicate->destination, &buffer->destination, buffer->destination.ss_len); min_c(buffer->source.ss_len, sizeof(sockaddr_storage)));
memcpy(&duplicate->destination, &buffer->destination,
min_c(buffer->destination.ss_len, sizeof(sockaddr_storage)));
duplicate->flags = buffer->flags; duplicate->flags = buffer->flags;
duplicate->interface = buffer->interface; duplicate->interface = buffer->interface;
duplicate->offset = buffer->offset;
duplicate->size = buffer->size; duplicate->size = buffer->size;
duplicate->protocol = buffer->protocol; duplicate->protocol = buffer->protocol;
@@ -346,11 +349,12 @@ clone_buffer(net_buffer *_buffer, bool shareFreeSpace)
{ {
net_buffer_private *buffer = (net_buffer_private *)_buffer; net_buffer_private *buffer = (net_buffer_private *)_buffer;
TRACE(("clone_buffer(buffer %p)\n", buffer));
net_buffer_private *clone = (net_buffer_private *)malloc(sizeof(struct net_buffer_private)); net_buffer_private *clone = (net_buffer_private *)malloc(sizeof(struct net_buffer_private));
if (clone == NULL) if (clone == NULL)
return NULL; return NULL;
data_node *node = &clone->first_node;
data_node *sourceNode = (data_node *)list_get_first_item(&buffer->buffers); data_node *sourceNode = (data_node *)list_get_first_item(&buffer->buffers);
if (sourceNode == NULL) { if (sourceNode == NULL) {
free(clone); free(clone);
@@ -361,7 +365,8 @@ clone_buffer(net_buffer *_buffer, bool shareFreeSpace)
// grab reference to this buffer - all additional nodes will get // grab reference to this buffer - all additional nodes will get
// theirs in add_data_node() // theirs in add_data_node()
atomic_add(&sourceNode->header->ref_count, 1); acquire_data_header(sourceNode->header);
data_node *node = &clone->first_node;
node->header = sourceNode->header; node->header = sourceNode->header;
node->located = NULL; node->located = NULL;
@@ -400,11 +405,14 @@ clone_buffer(net_buffer *_buffer, bool shareFreeSpace)
// copy meta data from source buffer // copy meta data from source buffer
memcpy(&clone->source, &buffer->source, buffer->source.ss_len); memcpy(&clone->source, &buffer->source,
memcpy(&clone->destination, &buffer->destination, buffer->destination.ss_len); min_c(buffer->source.ss_len, sizeof(sockaddr_storage)));
memcpy(&clone->destination, &buffer->destination,
min_c(buffer->destination.ss_len, sizeof(sockaddr_storage)));
clone->flags = buffer->flags; clone->flags = buffer->flags;
clone->interface = buffer->interface; clone->interface = buffer->interface;
clone->offset = buffer->offset;
clone->size = buffer->size; clone->size = buffer->size;
clone->protocol = buffer->protocol; clone->protocol = buffer->protocol;
@@ -1058,7 +1066,7 @@ get_iovecs(net_buffer *_buffer, struct iovec *iovecs, uint32 vecCount)
data_node *node = (data_node *)list_get_first_item(&buffer->buffers); data_node *node = (data_node *)list_get_first_item(&buffer->buffers);
uint32 count = 0; uint32 count = 0;
while (count < vecCount) { while (node != NULL && count < vecCount) {
if (node->used > 0) { if (node->used > 0) {
iovecs[count].iov_base = node->start; iovecs[count].iov_base = node->start;
iovecs[count].iov_len = node->used; iovecs[count].iov_len = node->used;
@@ -1066,8 +1074,6 @@ get_iovecs(net_buffer *_buffer, struct iovec *iovecs, uint32 vecCount)
} }
node = (data_node *)list_get_next_item(&buffer->buffers, node); node = (data_node *)list_get_next_item(&buffer->buffers, node);
if (node == NULL)
break;
} }
return count; return count;
@@ -1081,13 +1087,11 @@ count_iovecs(net_buffer *_buffer)
data_node *node = (data_node *)list_get_first_item(&buffer->buffers); data_node *node = (data_node *)list_get_first_item(&buffer->buffers);
uint32 count = 0; uint32 count = 0;
while (true) { while (node != NULL) {
if (node->used > 0) if (node->used > 0)
count++; count++;
node = (data_node *)list_get_next_item(&buffer->buffers, node); node = (data_node *)list_get_next_item(&buffer->buffers, node);
if (node == NULL)
break;
} }
return count; return count;