From 49e00d1f99fa525355674427039e360eb96c574b Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 2 May 2008 14:37:16 +0000 Subject: [PATCH] Moved the container management for ancillary data from the net_buffer module to the stack module. There's a dedicated struct ancillary_data_container, now. One can just set the container on a net_buffer. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25292 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/net/net_buffer.h | 17 +- headers/private/net/net_protocol.h | 7 +- headers/private/net/net_stack.h | 23 ++ .../kernel/network/protocols/unix/unix.cpp | 16 +- src/add-ons/kernel/network/stack/Jamfile | 1 + .../kernel/network/stack/ancillary_data.cpp | 203 ++++++++++++++++++ .../kernel/network/stack/ancillary_data.h | 29 +++ .../kernel/network/stack/net_buffer.cpp | 179 +++------------ .../kernel/network/stack/net_socket.cpp | 34 ++- src/add-ons/kernel/network/stack/stack.cpp | 8 + 10 files changed, 332 insertions(+), 185 deletions(-) create mode 100644 src/add-ons/kernel/network/stack/ancillary_data.cpp create mode 100644 src/add-ons/kernel/network/stack/ancillary_data.h diff --git a/headers/private/net/net_buffer.h b/headers/private/net/net_buffer.h index d5fcf30081..5f8088b499 100644 --- a/headers/private/net/net_buffer.h +++ b/headers/private/net/net_buffer.h @@ -37,11 +37,7 @@ typedef struct net_buffer { uint8 protocol; } net_buffer; -typedef struct ancillary_data_header { - int level; - int type; - size_t len; -} ancillary_data_header; +struct ancillary_data_container; struct net_buffer_module_info { module_info info; @@ -74,16 +70,11 @@ struct net_buffer_module_info { status_t (*associate_data)(net_buffer *buffer, void *data); - status_t (*attach_ancillary_data)(net_buffer *buffer, - const ancillary_data_header *header, const void *data, - void (*destructor)(const ancillary_data_header*, void*), - void **_allocatedData); - status_t (*detach_ancillary_data)(net_buffer *buffer, void *data, - bool destroy); + void (*set_ancillary_data)(net_buffer *buffer, + ancillary_data_container *container); + ancillary_data_container* (*get_ancillary_data)(net_buffer *buffer); void * (*transfer_ancillary_data)(net_buffer *from, net_buffer *to); - void * (*next_ancillary_data)(net_buffer *buffer, - void *previousData, ancillary_data_header *_header); status_t (*direct_access)(net_buffer *buffer, uint32 offset, size_t bytes, void **_data); diff --git a/headers/private/net/net_protocol.h b/headers/private/net/net_protocol.h index 5781b2d02d..1ae88fc878 100644 --- a/headers/private/net/net_protocol.h +++ b/headers/private/net/net_protocol.h @@ -16,6 +16,9 @@ #define LEVEL_DRIVER_IOCTL 0x0f000000 #define LEVEL_MASK 0x0fffffff +struct ancillary_data_container; +struct ancillary_data_header; + typedef struct net_protocol { struct net_protocol *next; struct net_protocol_module_info *module; @@ -69,8 +72,8 @@ struct net_protocol_module_info { status_t (*error_reply)(net_protocol *self, net_buffer *causedError, uint32 code, void *errorData); - status_t (*attach_ancillary_data)(net_protocol *self, net_buffer *buffer, - const cmsghdr *header); + status_t (*add_ancillary_data)(net_protocol *self, + ancillary_data_container *container, const cmsghdr *header); ssize_t (*process_ancillary_data)(net_protocol *self, const ancillary_data_header *header, const void *data, void *buffer, size_t bufferSize); diff --git a/headers/private/net/net_stack.h b/headers/private/net/net_stack.h index 1ca720f95e..a09ef6c5ed 100644 --- a/headers/private/net/net_stack.h +++ b/headers/private/net/net_stack.h @@ -24,6 +24,8 @@ struct net_domain; struct net_socket; struct net_timer; +typedef struct ancillary_data_container ancillary_data_container; + struct net_fifo { benaphore lock; sem_id notify; @@ -64,6 +66,12 @@ struct net_device_monitor { void (*event)(struct net_device_monitor *monitor, int32 event); }; +typedef struct ancillary_data_header { + int level; + int type; + size_t len; +} ancillary_data_header; + struct net_stack_module_info { module_info info; @@ -139,6 +147,21 @@ struct net_stack_module_info { bool (*is_restarted_syscall)(void); void (*store_syscall_restart_timeout)(bigtime_t timeout); bigtime_t (*restore_syscall_restart_timeout)(void); + + // ancillary data + ancillary_data_container* (*create_ancillary_data_container)(); + void (*delete_ancillary_data_container)( + ancillary_data_container* container); + status_t (*add_ancillary_data)(ancillary_data_container *container, + const ancillary_data_header *header, const void *data, + void (*destructor)(const ancillary_data_header*, void*), + void **_allocatedData); + status_t (*remove_ancillary_data)(ancillary_data_container *container, + void *data, bool destroy); + void* (*move_ancillary_data)(ancillary_data_container *from, + ancillary_data_container *to); + void* (*next_ancillary_data)(ancillary_data_container *container, + void *previousData, ancillary_data_header *_header); }; #endif // NET_STACK_H diff --git a/src/add-ons/kernel/network/protocols/unix/unix.cpp b/src/add-ons/kernel/network/protocols/unix/unix.cpp index 2332a81c3f..d204919c48 100644 --- a/src/add-ons/kernel/network/protocols/unix/unix.cpp +++ b/src/add-ons/kernel/network/protocols/unix/unix.cpp @@ -268,11 +268,11 @@ unix_error_reply(net_protocol *protocol, net_buffer *causedError, uint32 code, status_t -unix_attach_ancillary_data(net_protocol *self, net_buffer *buffer, +unix_add_ancillary_data(net_protocol *self, ancillary_data_container *container, const cmsghdr *header) { - TRACE("[%ld] unix_attach_ancillary_data(%p, %p, %p (level: %d, type: %d, " - "len: %d))\n", find_thread(NULL), self, buffer, header, + TRACE("[%ld] unix_add_ancillary_data(%p, %p, %p (level: %d, type: %d, " + "len: %d))\n", find_thread(NULL), self, container, header, header->cmsg_level, header->cmsg_type, (int)header->cmsg_len); // we support only SCM_RIGHTS @@ -302,17 +302,17 @@ unix_attach_ancillary_data(net_protocol *self, net_buffer *buffer, } } - // attach the ancillary data to the buffer + // attach the ancillary data to the container if (error == B_OK) { ancillary_data_header header; header.level = SOL_SOCKET; header.type = SCM_RIGHTS; header.len = count * sizeof(file_descriptor*); - TRACE("[%ld] unix_attach_ancillary_data(): attaching %d FDs to " - "buffer\n", find_thread(NULL), count); + TRACE("[%ld] unix_add_ancillary_data(): adding %d FDs to " + "container\n", find_thread(NULL), count); - error = gBufferModule->attach_ancillary_data(buffer, &header, + error = gStackModule->add_ancillary_data(container, &header, descriptors, destroy_scm_rights_descriptors, NULL); } @@ -468,7 +468,7 @@ net_protocol_module_info gUnixModule = { unix_deliver_data, unix_error, unix_error_reply, - unix_attach_ancillary_data, + unix_add_ancillary_data, unix_process_ancillary_data }; diff --git a/src/add-ons/kernel/network/stack/Jamfile b/src/add-ons/kernel/network/stack/Jamfile index 2a6ff8df09..2846f9c37b 100644 --- a/src/add-ons/kernel/network/stack/Jamfile +++ b/src/add-ons/kernel/network/stack/Jamfile @@ -15,6 +15,7 @@ UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ; UsePrivateHeaders net ; KernelAddon stack : + ancillary_data.cpp datalink.cpp domains.cpp interfaces.cpp diff --git a/src/add-ons/kernel/network/stack/ancillary_data.cpp b/src/add-ons/kernel/network/stack/ancillary_data.cpp new file mode 100644 index 0000000000..43f1749a60 --- /dev/null +++ b/src/add-ons/kernel/network/stack/ancillary_data.cpp @@ -0,0 +1,203 @@ +/* + * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + +#include "ancillary_data.h" + +#include +#include + +#include + +#include + + +#define MAX_ANCILLARY_DATA_SIZE 128 + + +struct ancillary_data : DoublyLinkedListLinkImpl { + void* Data() + { + return (char*)this + _ALIGN(sizeof(ancillary_data)); + } + + static ancillary_data* FromData(void* data) + { + return (ancillary_data*)((char*)data - _ALIGN(sizeof(ancillary_data))); + } + + ancillary_data_header header; + void (*destructor)(const ancillary_data_header*, void*); +}; + +typedef DoublyLinkedList ancillary_data_list; + +struct ancillary_data_container { + ancillary_data_list data_list; +}; + + +ancillary_data_container* +create_ancillary_data_container() +{ + return new(std::nothrow) ancillary_data_container; +} + + +void +delete_ancillary_data_container(ancillary_data_container* container) +{ + if (container == NULL) + return; + + while (ancillary_data* data = container->data_list.RemoveHead()) { + if (data->destructor != NULL) + data->destructor(&data->header, data->Data()); + free(data); + } +} + + +/*! + Adds ancillary data to the given container. + + \param container The container. + \param header Description of the data. + \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 + data as parameter when the container is destroyed. + \param _allocatedData Will be set to the storage allocated for the data. + \return \c B_OK when everything goes well, another error code otherwise. +*/ +status_t +add_ancillary_data(ancillary_data_container* container, + const ancillary_data_header* header, const void* data, + void (*destructor)(const ancillary_data_header*, void*), + void** _allocatedData) +{ + // check parameters + if (header == NULL) + return B_BAD_VALUE; + + if (header->len > MAX_ANCILLARY_DATA_SIZE) + return ENOBUFS; + + // allocate buffer + void *dataBuffer = malloc(_ALIGN(sizeof(ancillary_data)) + header->len); + if (dataBuffer == NULL) + return B_NO_MEMORY; + + // init and attach the structure + ancillary_data *ancillaryData = new(dataBuffer) ancillary_data; + ancillaryData->header = *header; + ancillaryData->destructor = destructor; + + container->data_list.Add(ancillaryData); + + if (data != NULL) + memcpy(ancillaryData->Data(), data, header->len); + + if (_allocatedData != NULL) + *_allocatedData = ancillaryData->Data(); + + return B_OK; +} + + +/*! + Removes ancillary data from the given container. The associated memory is + freed, i.e. the \a data pointer must no longer be used after calling this + function. Depending on \a destroy, the destructor is invoked before freeing + the data. + + \param container The container. + \param data Pointer to the data to be removed (as returned by + add_ancillary_data() or next_ancillary_data()). + \param destroy If \c true, the destructor, if one was passed to + add_ancillary_data(), is invoked for the data. + \return \c B_OK when everything goes well, another error code otherwise. +*/ +status_t +remove_ancillary_data(ancillary_data_container* container, void* data, + bool destroy) +{ + if (data == NULL) + return B_BAD_VALUE; + + ancillary_data *ancillaryData = ancillary_data::FromData(data); + + container->data_list.Remove(ancillaryData); + + if (destroy && ancillaryData->destructor != NULL) { + ancillaryData->destructor(&ancillaryData->header, + ancillaryData->Data()); + } + + free(ancillaryData); + + return B_OK; +} + + +/*! + Moves 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 remove the ancillary data. + \param to The container to which to add the ancillary data. + \return A pointer to the first of the moved ancillary data, if any, \c NULL + otherwise. +*/ +void * +move_ancillary_data(ancillary_data_container* from, + ancillary_data_container* to) +{ + if (from == NULL || to == NULL) + return NULL; + + ancillary_data *ancillaryData = from->data_list.Head(); + to->data_list.MoveFrom(&from->data_list); + + return ancillaryData != NULL ? ancillaryData->Data() : NULL; +} + + +/*! + Returns the next ancillary data. When iterating through the data, initially + a \c NULL pointer shall be passed as \a previousData, subsequently the + previously returned data pointer. After the last item, \c NULL is returned. + + Note, that it is not safe to call remove_ancillary_data() for a data item + and then pass that pointer to this function. First get the next item, then + remove the previous one. + + \param container The container. + \param previousData The pointer to the previous data returned by this + function. Initially \c NULL shall be passed. + \param header Pointer to allocated storage into which the data description + is written. May be \c NULL. + \return A pointer to the next ancillary data in the container. \c NULL after + the last one. +*/ +void* +next_ancillary_data(ancillary_data_container* container, void* previousData, + ancillary_data_header* _header) +{ + ancillary_data *ancillaryData; + + if (previousData == NULL) { + ancillaryData = container->data_list.Head(); + } else { + ancillaryData = ancillary_data::FromData(previousData); + ancillaryData = container->data_list.GetNext(ancillaryData); + } + + if (ancillaryData == NULL) + return NULL; + + if (_header != NULL) + *_header = ancillaryData->header; + + return ancillaryData->Data(); +} diff --git a/src/add-ons/kernel/network/stack/ancillary_data.h b/src/add-ons/kernel/network/stack/ancillary_data.h new file mode 100644 index 0000000000..cd194ccffb --- /dev/null +++ b/src/add-ons/kernel/network/stack/ancillary_data.h @@ -0,0 +1,29 @@ +/* + * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef NET_ANCILLARY_DATA_H +#define NET_ANCILLARY_DATA_H + +#include + + +struct ancillary_data_container; + +ancillary_data_container* create_ancillary_data_container(); +void delete_ancillary_data_container(ancillary_data_container* container); + +status_t add_ancillary_data(ancillary_data_container* container, + const ancillary_data_header* header, const void* data, + void (*destructor)(const ancillary_data_header*, void*), + void** _allocatedData); +status_t remove_ancillary_data(ancillary_data_container* container, void* data, + bool destroy); +void* move_ancillary_data(ancillary_data_container* from, + ancillary_data_container* to); + +void* next_ancillary_data(ancillary_data_container* container, + void* previousData, ancillary_data_header* _header); + + +#endif // NET_ANCILLARY_DATA_H diff --git a/src/add-ons/kernel/network/stack/net_buffer.cpp b/src/add-ons/kernel/network/stack/net_buffer.cpp index ff950e44c5..5c08cc2676 100644 --- a/src/add-ons/kernel/network/stack/net_buffer.cpp +++ b/src/add-ons/kernel/network/stack/net_buffer.cpp @@ -25,6 +25,8 @@ #include #include +#include "ancillary_data.h" + #include "paranoia_config.h" @@ -121,30 +123,11 @@ struct data_node { } }; -#define MAX_ANCILLARY_DATA_SIZE 128 - -struct ancillary_data : DoublyLinkedListLinkImpl { - void* Data() - { - return (char*)this + _ALIGN(sizeof(ancillary_data)); - } - - static ancillary_data* FromData(void* data) - { - return (ancillary_data*)((char*)data - _ALIGN(sizeof(ancillary_data))); - } - - ancillary_data_header header; - void (*destructor)(const ancillary_data_header*, void*); -}; - -typedef DoublyLinkedList ancillary_data_list; - struct net_buffer_private : net_buffer { struct list buffers; data_header *allocation_header; // the current place where we // allocate header space (nodes,...) - ancillary_data_list ancillary_data; + ancillary_data_container* ancillary_data; struct { struct sockaddr_storage source; @@ -1021,7 +1004,7 @@ create_buffer(size_t headerSpace) list_init(&buffer->buffers); list_add_item(&buffer->buffers, node); - new(&buffer->ancillary_data) ancillary_data_list; + buffer->ancillary_data = NULL; buffer->source = (sockaddr *)&buffer->storage.source; buffer->destination = (sockaddr *)&buffer->storage.destination; @@ -1063,11 +1046,7 @@ free_buffer(net_buffer *_buffer) remove_data_node(node); } - while (ancillary_data* data = buffer->ancillary_data.RemoveHead()) { - if (data->destructor != NULL) - data->destructor(&data->header, data->Data()); - free(data); - } + delete_ancillary_data_container(buffer->ancillary_data); release_data_header(buffer->allocation_header); @@ -1873,89 +1852,17 @@ append_cloned_data(net_buffer *_buffer, net_buffer *_source, uint32 offset, } -/*! - Attaches ancillary data to the given buffer. The data are completely - orthogonal to the data the buffer stores. - - \param buffer The buffer. - \param header Description of the data. - \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 - data as parameter when the buffer is destroyed. - \param _allocatedData Will be set to the storage allocated for the data. - \return \c B_OK when everything goes well, another error code otherwise. -*/ -static status_t -attach_ancillary_data(net_buffer *_buffer, const ancillary_data_header *header, - const void *data, void (*destructor)(const ancillary_data_header*, void*), - void **_allocatedData) +void +set_ancillary_data(net_buffer *buffer, ancillary_data_container *container) { - // TODO: Obviously it would be nice to allocate the memory for the - // ancillary data in the buffer. - net_buffer_private *buffer = (net_buffer_private *)_buffer; - - // check parameters - if (header == NULL) - return B_BAD_VALUE; - - if (header->len > MAX_ANCILLARY_DATA_SIZE) - return ENOBUFS; - - // allocate buffer - void *dataBuffer = malloc(_ALIGN(sizeof(ancillary_data)) + header->len); - if (dataBuffer == NULL) - return B_NO_MEMORY; - - // init and attach the structure - ancillary_data *ancillaryData = new(dataBuffer) ancillary_data; - ancillaryData->header = *header; - ancillaryData->destructor = destructor; - - buffer->ancillary_data.Add(ancillaryData); - - if (data != NULL) - memcpy(ancillaryData->Data(), data, header->len); - - if (_allocatedData != NULL) - *_allocatedData = ancillaryData->Data(); - - return B_OK; + ((net_buffer_private*)buffer)->ancillary_data = container; } -/*! - Detaches ancillary data from the given buffer. The associated memory is - free, i.e. the \a data pointer must no longer be used after calling this - function. Depending on \a destroy, the destructor is invoked before freeing - the data. - - \param buffer The buffer. - \param data Pointer to the data to be removed (as returned by - attach_ancillary_data() or next_ancillary_data()). - \param destroy If \c true, the destructor, if one was passed to - attach_ancillary_data(), is invoked for the data. - \return \c B_OK when everything goes well, another error code otherwise. -*/ -static status_t -detach_ancillary_data(net_buffer *_buffer, void *data, bool destroy) +ancillary_data_container* +get_ancillary_data(net_buffer *buffer) { - net_buffer_private *buffer = (net_buffer_private *)_buffer; - - if (data == NULL) - return B_BAD_VALUE; - - ancillary_data *ancillaryData = ancillary_data::FromData(data); - - buffer->ancillary_data.Remove(ancillaryData); - - if (destroy && ancillaryData->destructor != NULL) { - ancillaryData->destructor(&ancillaryData->header, - ancillaryData->Data()); - } - - free(ancillaryData); - - return B_OK; + return ((net_buffer_private*)buffer)->ancillary_data; } @@ -1965,7 +1872,7 @@ detach_ancillary_data(net_buffer *_buffer, void *data, bool destroy) transfers or copies ancillary data from one buffer to another. \param from The buffer from which to remove the ancillary data. - \param to The buffer to which to add teh ancillary data. + \param to The buffer to which to add the ancillary data. \return A pointer to the first of the moved ancillary data, if any, \c NULL otherwise. */ @@ -1978,52 +1885,23 @@ transfer_ancillary_data(net_buffer *_from, net_buffer *_to) if (from == NULL || to == NULL) return NULL; - ancillary_data *ancillaryData = from->ancillary_data.Head(); - to->ancillary_data.MoveFrom(&from->ancillary_data); - - return ancillaryData != NULL ? ancillaryData->Data() : NULL; -} - - -/*! - Returns the next ancillary data. When iterating over the data, initially - a \c NULL pointer shall be passed as \a previousData, subsequently the - previously returned data pointer. After the last item, \c NULL is returned. - - Note, that it is not safe to call detach_ancillary_data() for a data item - and then pass that pointer to this function. First get the next item, then - detach the previous one. - - \param buffer The buffer. - \param previousData The pointer to the previous data returned by this - function. Initially \c NULL shall be passed. - \param header Pointer to allocated storage into which the data description - is written. May be \c NULL. - \return A pointer to the next ancillary data in the buffer. \c NULL after - the last one. -*/ -static void* -next_ancillary_data(net_buffer *_buffer, void *previousData, - ancillary_data_header *_header) -{ - net_buffer_private *buffer = (net_buffer_private *)_buffer; - - ancillary_data *ancillaryData; - - if (previousData == NULL) { - ancillaryData = buffer->ancillary_data.Head(); - } else { - ancillaryData = ancillary_data::FromData(previousData); - ancillaryData = buffer->ancillary_data.GetNext(ancillaryData); - } - - if (ancillaryData == NULL) + if (from->ancillary_data == NULL) return NULL; - if (_header != NULL) - *_header = ancillaryData->header; + if (to->ancillary_data == NULL) { + // no ancillary data in the target buffer + to->ancillary_data = from->ancillary_data; + from->ancillary_data = NULL; + return next_ancillary_data(to->ancillary_data, NULL, NULL); + } - return ancillaryData->Data(); + // both have ancillary data + void *data = move_ancillary_data(from->ancillary_data, + to->ancillary_data); + delete_ancillary_data_container(from->ancillary_data); + from->ancillary_data = NULL; + + return data; } @@ -2228,10 +2106,9 @@ net_buffer_module_info gNetBufferModule = { NULL, // associate_data - attach_ancillary_data, - detach_ancillary_data, + set_ancillary_data, + get_ancillary_data, transfer_ancillary_data, - next_ancillary_data, direct_access, read_data, diff --git a/src/add-ons/kernel/network/stack/net_socket.cpp b/src/add-ons/kernel/network/stack/net_socket.cpp index db8a25223f..83ac2d5153 100644 --- a/src/add-ons/kernel/network/stack/net_socket.cpp +++ b/src/add-ons/kernel/network/stack/net_socket.cpp @@ -30,6 +30,7 @@ #include #include +#include "ancillary_data.h" #include "utility.h" @@ -134,8 +135,8 @@ err1: static status_t -attach_ancillary_data(net_socket *socket, net_buffer *buffer, void *data, - size_t dataLen) +add_ancillary_data(net_socket *socket, ancillary_data_container* container, + void *data, size_t dataLen) { cmsghdr *header = (cmsghdr*)data; @@ -143,11 +144,11 @@ attach_ancillary_data(net_socket *socket, net_buffer *buffer, void *data, if (header->cmsg_len < sizeof(cmsghdr) || header->cmsg_len > dataLen) return B_BAD_VALUE; - if (socket->first_info->attach_ancillary_data == NULL) + if (socket->first_info->add_ancillary_data == NULL) return EOPNOTSUPP; - status_t status = socket->first_info->attach_ancillary_data( - socket->first_protocol, buffer, header); + status_t status = socket->first_info->add_ancillary_data( + socket->first_protocol, container, header); if (status != B_OK) return status; @@ -160,17 +161,20 @@ attach_ancillary_data(net_socket *socket, net_buffer *buffer, void *data, static status_t -process_ancillary_data(net_socket *socket, net_buffer *buffer, msghdr *_header) +process_ancillary_data(net_socket *socket, ancillary_data_container* container, + msghdr *_header) { + if (container == NULL) + return B_OK; + uint8 *dataBuffer = (uint8*)_header->msg_control; int dataBufferLen = _header->msg_controllen; ancillary_data_header header; void *data = NULL; - while ((data = gNetBufferModule.next_ancillary_data(buffer, data, &header)) - != NULL) { + while ((data = next_ancillary_data(container, data, &header)) != NULL) { if (socket->first_info->process_ancillary_data == NULL) return EOPNOTSUPP; @@ -943,7 +947,8 @@ socket_receive(net_socket *socket, msghdr *header, void *data, size_t length, // process ancillary data if (header != NULL) { if (buffer != NULL && header->msg_control != NULL) { - status = process_ancillary_data(socket, buffer, header); + status = process_ancillary_data(socket, + gNetBufferModule.get_ancillary_data(buffer), header); if (status != B_OK) { gNetBufferModule.free(buffer); return status; @@ -1129,8 +1134,15 @@ socket_send(net_socket *socket, msghdr *header, const void *data, size_t length, // attach ancillary data to the first buffer status_t status = B_OK; if (ancillaryData != NULL) { - status = attach_ancillary_data(socket, buffer, ancillaryData, - ancillaryDataLen); + ancillary_data_container *container + = create_ancillary_data_container(); + if (container != NULL) { + gNetBufferModule.set_ancillary_data(buffer, container); + status = add_ancillary_data(socket, container, ancillaryData, + ancillaryDataLen); + } else + status = B_NO_MEMORY; + ancillaryData = NULL; } diff --git a/src/add-ons/kernel/network/stack/stack.cpp b/src/add-ons/kernel/network/stack/stack.cpp index 7cf6be04f2..31c11bdf87 100644 --- a/src/add-ons/kernel/network/stack/stack.cpp +++ b/src/add-ons/kernel/network/stack/stack.cpp @@ -7,6 +7,7 @@ */ +#include "ancillary_data.h" #include "domains.h" #include "interfaces.h" #include "link.h" @@ -922,6 +923,13 @@ net_stack_module_info gNetStackModule = { is_restarted_syscall, store_syscall_restart_timeout, restore_syscall_restart_timeout, + + create_ancillary_data_container, + delete_ancillary_data_container, + add_ancillary_data, + remove_ancillary_data, + move_ancillary_data, + next_ancillary_data }; module_info *modules[] = {