network/stack: Add clone_ancillary_data.

Change-Id: I98a56344ffbf0c691a797ad7ce69ba1de08bbbee
Reviewed-on: https://review.haiku-os.org/c/haiku/+/9859
Reviewed-by: waddlesplash <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
Jérôme Duval
2025-11-15 22:30:45 +00:00
parent 646294695d
commit 8dcdf257f9
5 changed files with 54 additions and 2 deletions
+3
View File
@@ -175,6 +175,7 @@ struct net_stack_module_info {
status_t (*add_ancillary_data)(ancillary_data_container* container, status_t (*add_ancillary_data)(ancillary_data_container* container,
const ancillary_data_header* header, const void* data, const ancillary_data_header* header, const void* data,
void (*destructor)(const ancillary_data_header*, void*), void (*destructor)(const ancillary_data_header*, void*),
void (*clone)(const ancillary_data_header*, void*),
void** _allocatedData); void** _allocatedData);
status_t (*remove_ancillary_data)(ancillary_data_container* container, status_t (*remove_ancillary_data)(ancillary_data_container* container,
void* data, bool destroy); void* data, bool destroy);
@@ -182,6 +183,8 @@ struct net_stack_module_info {
ancillary_data_container* to); ancillary_data_container* to);
void* (*next_ancillary_data)(const ancillary_data_container* container, void* (*next_ancillary_data)(const ancillary_data_container* container,
void* previousData, ancillary_data_header* _header); void* previousData, ancillary_data_header* _header);
status_t (*clone_ancillary_data)(const ancillary_data_container* from,
ancillary_data_container* to);
}; };
@@ -334,7 +334,7 @@ unix_add_ancillary_data(net_protocol *self, ancillary_data_container *container,
"container\n", find_thread(NULL), count); "container\n", find_thread(NULL), count);
error = gStackModule->add_ancillary_data(container, &header, error = gStackModule->add_ancillary_data(container, &header,
descriptors, destroy_scm_rights_descriptors, NULL); descriptors, destroy_scm_rights_descriptors, NULL, NULL);
} }
// cleanup on error // cleanup on error
@@ -29,6 +29,7 @@ struct ancillary_data : DoublyLinkedListLinkImpl<ancillary_data> {
ancillary_data_header header; ancillary_data_header header;
void (*destructor)(const ancillary_data_header*, void*); void (*destructor)(const ancillary_data_header*, void*);
void (*clone)(const ancillary_data_header*, void*);
}; };
typedef DoublyLinkedList<ancillary_data> ancillary_data_list; typedef DoublyLinkedList<ancillary_data> ancillary_data_list;
@@ -69,6 +70,8 @@ delete_ancillary_data_container(ancillary_data_container* container)
\param data If not \c NULL, the data are copied into the allocated storage. \param data If not \c NULL, the data are copied into the allocated storage.
\param destructor If not \c NULL, this function will be invoked with the \param destructor If not \c NULL, this function will be invoked with the
data as parameter when the container is destroyed. data as parameter when the container is destroyed.
\param clone If not \c NULL, this function will be invoked with the
data as parameter when the container is cloned.
\param _allocatedData Will be set to the storage allocated for the data. \param _allocatedData Will be set to the storage allocated for the data.
\return \c B_OK when everything goes well, another error code otherwise. \return \c B_OK when everything goes well, another error code otherwise.
*/ */
@@ -76,6 +79,7 @@ status_t
add_ancillary_data(ancillary_data_container* container, add_ancillary_data(ancillary_data_container* container,
const ancillary_data_header* header, const void* data, const ancillary_data_header* header, const void* data,
void (*destructor)(const ancillary_data_header*, void*), void (*destructor)(const ancillary_data_header*, void*),
void (*clone)(const ancillary_data_header*, void*),
void** _allocatedData) void** _allocatedData)
{ {
// check parameters // check parameters
@@ -94,6 +98,7 @@ add_ancillary_data(ancillary_data_container* container,
ancillary_data *ancillaryData = new(dataBuffer) ancillary_data; ancillary_data *ancillaryData = new(dataBuffer) ancillary_data;
ancillaryData->header = *header; ancillaryData->header = *header;
ancillaryData->destructor = destructor; ancillaryData->destructor = destructor;
ancillaryData->clone = clone;
container->data_list.Add(ancillaryData); container->data_list.Add(ancillaryData);
@@ -203,3 +208,43 @@ next_ancillary_data(const ancillary_data_container* container, void* previousDat
return ancillaryData->Data(); return ancillaryData->Data();
} }
/*!
Clones all ancillary data from container \c from to the end of the list of
ancillary data of container \c to.
\param from The container from which to clone the ancillary data.
\param to The container to which to add the ancillary data.
\return \c B_OK when everything goes well, another error code otherwise.
*/
status_t
clone_ancillary_data(const ancillary_data_container* from,
ancillary_data_container* to)
{
ancillary_data *ancillaryData = from->data_list.Head();
while (ancillaryData != NULL) {
// allocate buffer
void *dataBuffer = malloc(_ALIGN(sizeof(ancillary_data)) + ancillaryData->header.len);
if (dataBuffer == NULL)
return B_NO_MEMORY;
// init and attach the structure
ancillary_data *clone = new(dataBuffer) ancillary_data;
clone->header = ancillaryData->header;
if (ancillaryData->clone != NULL)
ancillaryData->clone(&ancillaryData->header, ancillaryData->Data());
clone->destructor = ancillaryData->destructor;
clone->clone = ancillaryData->clone;
to->data_list.Add(clone);
if (ancillaryData->Data() != NULL)
memcpy(clone->Data(), ancillaryData->Data(), ancillaryData->header.len);
ancillaryData = from->data_list.GetNext(ancillaryData);
}
return B_OK;
}
@@ -16,6 +16,7 @@ void delete_ancillary_data_container(ancillary_data_container* container);
status_t add_ancillary_data(ancillary_data_container* container, status_t add_ancillary_data(ancillary_data_container* container,
const ancillary_data_header* header, const void* data, const ancillary_data_header* header, const void* data,
void (*destructor)(const ancillary_data_header*, void*), void (*destructor)(const ancillary_data_header*, void*),
void (*clone)(const ancillary_data_header*, void*),
void** _allocatedData); void** _allocatedData);
status_t remove_ancillary_data(ancillary_data_container* container, void* data, status_t remove_ancillary_data(ancillary_data_container* container, void* data,
bool destroy); bool destroy);
@@ -24,6 +25,8 @@ void* move_ancillary_data(ancillary_data_container* from,
void* next_ancillary_data(const ancillary_data_container* container, void* next_ancillary_data(const ancillary_data_container* container,
void* previousData, ancillary_data_header* _header); void* previousData, ancillary_data_header* _header);
status_t clone_ancillary_data(const ancillary_data_container* from,
ancillary_data_container* to);
#endif // NET_ANCILLARY_DATA_H #endif // NET_ANCILLARY_DATA_H
+2 -1
View File
@@ -989,7 +989,8 @@ net_stack_module_info gNetStackModule = {
add_ancillary_data, add_ancillary_data,
remove_ancillary_data, remove_ancillary_data,
move_ancillary_data, move_ancillary_data,
next_ancillary_data next_ancillary_data,
clone_ancillary_data
}; };
module_info* modules[] = { module_info* modules[] = {