introduced a new helper class DatagramSocket which provides a consistent base interface and functionality for the implementation of datagram-based sockets.

- made the ipv4 raw, udp and link protocols use DatagramSocket.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20672 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos 2007-04-13 00:55:32 +00:00
parent effe53fae9
commit bfb45f717c
7 changed files with 355 additions and 173 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef NET_BUFFER_UTILITIES_H

View File

@ -0,0 +1,288 @@
/*
* Copyright 2007, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Hugo Santos, hugosantos@gmail.com
*/
#ifndef PROTOCOL_UTILITIES_H
#define PROTOCOL_UTILITIES_H
#include <lock.h>
#include <util/AutoLock.h>
#include <util/DoublyLinkedList.h>
#include <net_buffer.h>
#include <net_socket.h>
#include <net_stack.h>
class BenaphoreLocking {
public:
typedef benaphore Type;
typedef BenaphoreLocker AutoLocker;
static status_t Init(benaphore *lock, const char *name)
{ return benaphore_init(lock, name); }
static void Destroy(benaphore *lock) { benaphore_destroy(lock); }
static status_t Lock(benaphore *lock) { return benaphore_lock(lock); }
static status_t Unlock(benaphore *lock) { return benaphore_unlock(lock); }
};
extern net_stack_module_info *gStackModule;
extern net_buffer_module_info *gBufferModule;
class NetModuleBundle {
public:
static net_stack_module_info *Stack() { return gStackModule; }
static net_buffer_module_info *Buffer() { return gBufferModule; }
};
template<typename LockingBase = BenaphoreLocking,
typename ModuleBundle = NetModuleBundle>
class DatagramSocket {
public:
DatagramSocket(const char *name, net_socket *socket);
~DatagramSocket();
status_t InitCheck() const;
status_t Enqueue(net_buffer *buffer);
status_t EnqueueClone(net_buffer *buffer);
net_buffer *Dequeue(bool clone);
status_t BlockingDequeue(bool clone, bigtime_t timeout,
net_buffer **_buffer);
status_t SocketDequeue(uint32 flags, net_buffer **_buffer);
void Clear();
size_t AvailableData() const;
void WakeAll();
protected:
status_t _Enqueue(net_buffer *buffer);
status_t _EnqueueClone(net_buffer *buffer);
net_buffer *_Dequeue(bool clone);
void _Clear();
status_t _Wait(bigtime_t timeout);
void _NotifyOneReader(bool notifySocket);
bool _IsEmpty() const { return fBuffers.IsEmpty(); }
bigtime_t _SocketTimeout(uint32 flags) const;
typedef typename LockingBase::Type LockType;
typedef typename LockingBase::AutoLocker AutoLocker;
typedef DoublyLinkedListCLink<net_buffer> NetBufferLink;
typedef DoublyLinkedList<net_buffer, NetBufferLink> BufferList;
status_t fStatus;
net_socket *fSocket;
sem_id fNotify;
BufferList fBuffers;
size_t fCurrentBytes;
mutable LockType fLock;
};
#define DECL_DATAGRAM_SOCKET(args) \
template<typename LockingBase, typename ModuleBundle> args \
DatagramSocket<LockingBase, ModuleBundle>
DECL_DATAGRAM_SOCKET(inline)::DatagramSocket(const char *name,
net_socket *socket)
: fSocket(socket), fCurrentBytes(0)
{
fStatus = LockingBase::Init(&fLock, name);
if (fStatus >= B_OK)
fNotify = create_sem(0, name);
}
DECL_DATAGRAM_SOCKET(inline)::~DatagramSocket()
{
_Clear();
if (fStatus >= B_OK) {
delete_sem(fNotify);
LockingBase::Destroy(&fLock);
}
}
DECL_DATAGRAM_SOCKET(inline status_t)::InitCheck() const
{
if (fStatus < 0)
return fStatus;
return fNotify;
}
DECL_DATAGRAM_SOCKET(inline status_t)::Enqueue(net_buffer *buffer)
{
AutoLocker _(fLock);
return _Enqueue(buffer);
}
DECL_DATAGRAM_SOCKET(inline status_t)::_Enqueue(net_buffer *buffer)
{
if (fSocket->receive.buffer_size > 0
&& (fCurrentBytes + buffer->size) > fSocket->receive.buffer_size)
return ENOBUFS;
fBuffers.Add(buffer);
fCurrentBytes += buffer->size;
_NotifyOneReader(true);
return B_OK;
}
DECL_DATAGRAM_SOCKET(inline status_t)::EnqueueClone(net_buffer *_buffer)
{
AutoLocker _(fLock);
return _EnqueueClone(_buffer);
}
DECL_DATAGRAM_SOCKET(inline status_t)::_EnqueueClone(net_buffer *_buffer)
{
net_buffer *buffer = ModuleBundle::Buffer()->clone(_buffer, false);
if (buffer == NULL)
return B_NO_MEMORY;
status_t status = _Enqueue(buffer);
if (status < B_OK)
ModuleBundle::Buffer()->free(buffer);
return status;
}
DECL_DATAGRAM_SOCKET(inline net_buffer *)::Dequeue(bool clone)
{
AutoLocker _(fLock);
return _Dequeue(clone);
}
DECL_DATAGRAM_SOCKET(inline net_buffer *)::_Dequeue(bool clone)
{
if (fBuffers.IsEmpty())
return NULL;
if (clone)
return ModuleBundle::Buffer()->clone(fBuffers.Head(), false);
net_buffer *buffer = fBuffers.RemoveHead();
fCurrentBytes -= buffer->size;
return buffer;
}
DECL_DATAGRAM_SOCKET(inline status_t)::BlockingDequeue(bool clone,
bigtime_t timeout, net_buffer **_buffer)
{
AutoLocker _(fLock);
bool waited = false;
while (fBuffers.IsEmpty()) {
status_t status = _Wait(timeout);
if (status < B_OK)
return status;
waited = true;
}
*_buffer = _Dequeue(clone);
if (clone && waited) {
// we were signalled there was a new buffer in the
// list; but since we are cloning, notify the next
// waiting reader.
_NotifyOneReader(false);
}
if (*_buffer == NULL)
return B_NO_MEMORY;
return B_OK;
}
DECL_DATAGRAM_SOCKET(inline status_t)::SocketDequeue(uint32 flags,
net_buffer **_buffer)
{
return BlockingDequeue(flags & MSG_PEEK, _SocketTimeout(flags), _buffer);
}
DECL_DATAGRAM_SOCKET(inline void)::Clear()
{
AutoLocker _(fLock);
_Clear();
}
DECL_DATAGRAM_SOCKET(inline void)::_Clear()
{
BufferList::Iterator it = fBuffers.GetIterator();
while (it.HasNext())
ModuleBundle::Buffer()->free(it.Next());
fCurrentBytes = 0;
}
DECL_DATAGRAM_SOCKET(inline size_t)::AvailableData() const
{
AutoLocker _(fLock);
return fCurrentBytes;
}
DECL_DATAGRAM_SOCKET(inline status_t)::_Wait(bigtime_t timeout)
{
LockingBase::Unlock(&fLock);
status_t status = acquire_sem_etc(fNotify, 1, B_CAN_INTERRUPT
| B_ABSOLUTE_TIMEOUT, timeout);
LockingBase::Lock(&fLock);
return status;
}
DECL_DATAGRAM_SOCKET(inline void)::WakeAll()
{
release_sem_etc(fNotify, 0, B_RELEASE_ALL);
}
DECL_DATAGRAM_SOCKET(inline void)::_NotifyOneReader(bool notifySocket)
{
release_sem_etc(fNotify, 1, B_RELEASE_IF_WAITING_ONLY
| B_DO_NOT_RESCHEDULE);
if (notifySocket)
ModuleBundle::Stack()->notify_socket(fSocket, B_SELECT_READ,
fCurrentBytes);
}
DECL_DATAGRAM_SOCKET(inline bigtime_t)::_SocketTimeout(uint32 flags) const
{
bigtime_t timeout = fSocket->receive.timeout;
if (flags & MSG_DONTWAIT)
timeout = 0;
else if (timeout != 0 && timeout != B_INFINITE_TIMEOUT)
timeout += system_time();
return timeout;
}
#endif

View File

@ -13,6 +13,7 @@
#include <net_protocol.h>
#include <net_stack.h>
#include <NetBufferUtilities.h>
#include <ProtocolUtilities.h>
#include <ByteOrder.h>
#include <KernelExport.h>
@ -110,22 +111,9 @@ class FragmentPacket {
typedef DoublyLinkedList<class RawSocket> RawSocketList;
class RawSocket : public DoublyLinkedListLinkImpl<RawSocket> {
class RawSocket : public DoublyLinkedListLinkImpl<RawSocket>, public DatagramSocket<> {
public:
RawSocket(net_socket *socket);
~RawSocket();
status_t InitCheck();
status_t Read(size_t numBytes, uint32 flags, bigtime_t timeout,
net_buffer **_buffer);
ssize_t BytesAvailable();
status_t Write(net_buffer *buffer);
private:
net_socket *fSocket;
net_fifo fFifo;
};
struct ipv4_protocol : net_protocol {
@ -142,10 +130,11 @@ struct ipv4_protocol : net_protocol {
extern net_protocol_module_info gIPv4Module;
// we need this in ipv4_std_ops() for registering the AF_INET domain
net_stack_module_info *gStackModule;
net_buffer_module_info *gBufferModule;
static struct net_domain *sDomain;
static net_datalink_module_info *sDatalinkModule;
static net_stack_module_info *sStackModule;
struct net_buffer_module_info *gBufferModule;
static int32 sPacketID;
static RawSocketList sRawSockets;
static benaphore sRawSocketsLock;
@ -156,56 +145,8 @@ static benaphore sReceivingProtocolLock;
RawSocket::RawSocket(net_socket *socket)
:
fSocket(socket)
: DatagramSocket<>("ipv4 raw socket", socket)
{
status_t status = sStackModule->init_fifo(&fFifo, "ipv4 raw socket", 65536);
if (status < B_OK)
fFifo.notify = status;
}
RawSocket::~RawSocket()
{
if (fFifo.notify >= B_OK)
sStackModule->uninit_fifo(&fFifo);
}
status_t
RawSocket::InitCheck()
{
return fFifo.notify >= B_OK ? B_OK : fFifo.notify;
}
status_t
RawSocket::Read(size_t numBytes, uint32 flags, bigtime_t timeout,
net_buffer **_buffer)
{
net_buffer *buffer;
status_t status = sStackModule->fifo_dequeue_buffer(&fFifo,
flags, timeout, &buffer);
if (status < B_OK)
return status;
*_buffer = buffer;
return B_OK;
}
ssize_t
RawSocket::BytesAvailable()
{
return fFifo.current_bytes;
}
status_t
RawSocket::Write(net_buffer *source)
{
return sStackModule->fifo_socket_enqueue_buffer(&fFifo, fSocket,
B_SELECT_READ, source);
}
@ -218,14 +159,14 @@ FragmentPacket::FragmentPacket(const ipv4_packet_key &key)
fReceivedLastFragment(false),
fBytesLeft(IP_MAXPACKET)
{
sStackModule->init_timer(&fTimer, StaleTimer, this);
gStackModule->init_timer(&fTimer, StaleTimer, this);
}
FragmentPacket::~FragmentPacket()
{
// cancel the kill timer
sStackModule->set_timer(&fTimer, -1);
gStackModule->set_timer(&fTimer, -1);
// delete all fragments
net_buffer *buffer;
@ -240,7 +181,7 @@ FragmentPacket::AddFragment(uint16 start, uint16 end, net_buffer *buffer,
bool lastFragment)
{
// restart the timer
sStackModule->set_timer(&fTimer, FRAGMENT_TIMEOUT);
gStackModule->set_timer(&fTimer, FRAGMENT_TIMEOUT);
if (start >= end) {
// invalid fragment
@ -595,7 +536,7 @@ send_fragments(ipv4_protocol *protocol, struct net_route *route,
header->fragment_offset = htons((lastFragment ? 0 : IP_MORE_FRAGMENTS)
| (fragmentOffset >> 3));
header->checksum = 0;
header->checksum = sStackModule->checksum((uint8 *)header, headerLength);
header->checksum = gStackModule->checksum((uint8 *)header, headerLength);
// TODO: compute the checksum only for those parts that changed?
dprintf(" send fragment of %ld bytes (%ld bytes left)\n", fragmentLength, bytesLeft);
@ -644,10 +585,8 @@ raw_receive_data(net_buffer *buffer)
RawSocketList::Iterator iterator = sRawSockets.GetIterator();
while (iterator.HasNext()) {
RawSocket *raw = iterator.Next();
raw->Write(buffer);
}
while (iterator.HasNext())
iterator.Next()->EnqueueClone(buffer);
}
@ -664,7 +603,7 @@ receiving_protocol(uint8 protocol)
if (module != NULL)
return module;
if (sStackModule->get_domain_receiving_protocol(sDomain, protocol, &module) == B_OK)
if (gStackModule->get_domain_receiving_protocol(sDomain, protocol, &module) == B_OK)
sReceivingProtocol[protocol] = module;
return module;
@ -1016,7 +955,7 @@ ipv4_read_data(net_protocol *_protocol, size_t numBytes, uint32 flags,
return B_ERROR;
TRACE(("read is waiting for data...\n"));
return raw->Read(numBytes, flags, protocol->socket->receive.timeout, _buffer);
return raw->SocketDequeue(flags, _buffer);
}
@ -1028,7 +967,7 @@ ipv4_read_avail(net_protocol *_protocol)
if (raw == NULL)
return B_ERROR;
return raw->BytesAvailable();
return raw->AvailableData();
}
@ -1175,7 +1114,7 @@ ipv4_error_reply(net_protocol *protocol, net_buffer *causedError, uint32 code,
status_t
init_ipv4()
{
status_t status = get_module(NET_STACK_MODULE_NAME, (module_info **)&sStackModule);
status_t status = get_module(NET_STACK_MODULE_NAME, (module_info **)&gStackModule);
if (status < B_OK)
return status;
status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule);
@ -1209,12 +1148,12 @@ init_ipv4()
// so we have to do it here, manually
// TODO: for modules, this shouldn't be required
status = sStackModule->register_domain_protocols(AF_INET, SOCK_RAW, 0,
status = gStackModule->register_domain_protocols(AF_INET, SOCK_RAW, 0,
"network/protocols/ipv4/v1", NULL);
if (status < B_OK)
goto err7;
status = sStackModule->register_domain(AF_INET, "internet", &gIPv4Module,
status = gStackModule->register_domain(AF_INET, "internet", &gIPv4Module,
&gIPv4AddressModule, &sDomain);
if (status < B_OK)
goto err7;
@ -1247,10 +1186,10 @@ uninit_ipv4()
// put all the domain receiving protocols we gathered so far
for (uint32 i = 0; i < 256; i++) {
if (sReceivingProtocol[i] != NULL)
sStackModule->put_domain_receiving_protocol(sDomain, i);
gStackModule->put_domain_receiving_protocol(sDomain, i);
}
sStackModule->unregister_domain(sDomain);
gStackModule->unregister_domain(sDomain);
benaphore_unlock(&sReceivingProtocolLock);
hash_uninit(sFragmentHash);

View File

@ -22,6 +22,7 @@
#include <NetBufferUtilities.h>
#include <NetUtilities.h>
#include <ProtocolUtilities.h>
#include <netinet/in.h>
#include <new>
@ -29,9 +30,6 @@
#include <string.h>
#include <utility>
// TODO move the locking from the FIFO to the whole Endpoint
// much like we did with the LinkProtocol.
//#define TRACE_UDP
#ifdef TRACE_UDP
# define TRACE_BLOCK(x) dump_block x
@ -64,12 +62,9 @@ typedef NetBufferField<uint16, offsetof(udp_header, udp_checksum)>
class UdpDomainSupport;
class UdpEndpoint : public net_protocol {
class UdpEndpoint : public net_protocol, public DatagramSocket<> {
public:
UdpEndpoint(net_socket *socket);
~UdpEndpoint();
status_t InitCheck() const;
status_t Bind(sockaddr *newAddr);
status_t Unbind(sockaddr *newAddr);
@ -110,8 +105,6 @@ private:
bool fActive;
// an active UdpEndpoint is part of the endpoint
// hash (and it is bound and optionally connected)
net_fifo fFifo;
// storage space for incoming data
};
@ -208,9 +201,9 @@ private:
static UdpEndpointManager *sUdpEndpointManager;
net_stack_module_info *gStackModule;
net_buffer_module_info *gBufferModule;
static net_datalink_module_info *sDatalinkModule;
static net_stack_module_info *sStackModule;
// #pragma mark -
@ -707,27 +700,10 @@ UdpEndpointManager::_GetDomain(net_domain *domain, bool create)
UdpEndpoint::UdpEndpoint(net_socket *socket)
:
DatagramSocket<>("udp endpoint", socket),
fDomain(NULL),
fActive(false)
{
status_t status = sStackModule->init_fifo(&fFifo, "UDP endpoint fifo",
socket->receive.buffer_size);
if (status < B_OK)
fFifo.notify = status;
}
UdpEndpoint::~UdpEndpoint()
{
if (fFifo.notify >= B_OK)
sStackModule->uninit_fifo(&fFifo);
}
status_t
UdpEndpoint::InitCheck() const
{
return fFifo.notify;
}
@ -945,9 +921,9 @@ UdpEndpoint::SendData(net_buffer *buffer)
ssize_t
UdpEndpoint::BytesAvailable()
{
// TODO protect this call
TRACE_EP("BytesAvailable(): %lu", fFifo.current_bytes);
return fFifo.current_bytes;
size_t bytes = AvailableData();
TRACE_EP("BytesAvailable(): %lu", bytes);
return bytes;
}
@ -956,16 +932,12 @@ UdpEndpoint::FetchData(size_t numBytes, uint32 flags, net_buffer **_buffer)
{
TRACE_EP("FetchData(%ld, 0x%lx)", numBytes, flags);
net_buffer *buffer;
status_t status = sStackModule->fifo_dequeue_buffer(&fFifo, flags,
socket->receive.timeout, &buffer);
status_t status = SocketDequeue(flags, _buffer);
TRACE_EP(" FetchData(): returned from fifo status=0x%lx", status);
if (status < B_OK)
return status;
TRACE_EP(" FetchData(): returns buffer with %ld bytes", buffer->size);
*_buffer = buffer;
TRACE_EP(" FetchData(): returns buffer with %ld bytes", (*_buffer)->size);
return B_OK;
}
@ -975,8 +947,7 @@ UdpEndpoint::StoreData(net_buffer *buffer)
{
TRACE_EP("StoreData(%p [%ld bytes])", buffer, buffer->size);
return sStackModule->fifo_socket_enqueue_buffer(&fFifo, socket,
B_SELECT_READ, buffer);
return EnqueueClone(buffer);
}
@ -1160,7 +1131,7 @@ init_udp()
status_t status;
TRACE_EPM("init_udp()");
status = get_module(NET_STACK_MODULE_NAME, (module_info **)&sStackModule);
status = get_module(NET_STACK_MODULE_NAME, (module_info **)&gStackModule);
if (status < B_OK)
return status;
status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule);
@ -1179,20 +1150,20 @@ init_udp()
if (status != B_OK)
goto err3;
status = sStackModule->register_domain_protocols(AF_INET, SOCK_DGRAM, IPPROTO_IP,
status = gStackModule->register_domain_protocols(AF_INET, SOCK_DGRAM, IPPROTO_IP,
"network/protocols/udp/v1",
"network/protocols/ipv4/v1",
NULL);
if (status < B_OK)
goto err4;
status = sStackModule->register_domain_protocols(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
status = gStackModule->register_domain_protocols(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
"network/protocols/udp/v1",
"network/protocols/ipv4/v1",
NULL);
if (status < B_OK)
goto err4;
status = sStackModule->register_domain_receiving_protocol(AF_INET, IPPROTO_UDP,
status = gStackModule->register_domain_receiving_protocol(AF_INET, IPPROTO_UDP,
"network/protocols/udp/v1");
if (status < B_OK)
goto err4;

View File

@ -20,6 +20,7 @@
#include <util/AutoLock.h>
#include <KernelExport.h>
#include <ProtocolUtilities.h>
#include <net/if_types.h>
#include <new>
@ -28,12 +29,18 @@
#include <sys/sockio.h>
class LinkProtocol : public net_protocol {
class LocalStackBundle {
public:
LinkProtocol();
~LinkProtocol();
static net_stack_module_info *Stack() { return &gNetStackModule; }
static net_buffer_module_info *Buffer() { return &gNetBufferModule; }
};
status_t InitCheck() const;
typedef DatagramSocket<BenaphoreLocking, LocalStackBundle> LocalDatagramSocket;
class LinkProtocol : public net_protocol, public LocalDatagramSocket {
public:
LinkProtocol(net_socket *socket);
~LinkProtocol();
status_t StartMonitoring(const char *);
status_t StopMonitoring();
@ -42,12 +49,8 @@ public:
ssize_t ReadAvail() const;
private:
status_t _Enqueue(net_buffer *buffer);
status_t _Unregister();
mutable benaphore fLock;
Fifo fFifo;
net_device_monitor fMonitor;
net_device_interface *fMonitoredDevice;
@ -59,11 +62,9 @@ private:
struct net_domain *sDomain;
LinkProtocol::LinkProtocol()
: fFifo("packet monitor fifo", 65536)
LinkProtocol::LinkProtocol(net_socket *socket)
: LocalDatagramSocket("packet capture", socket)
{
benaphore_init(&fLock, "packet monitor lock");
fMonitor.cookie = this;
fMonitor.receive = _MonitorData;
fMonitor.event = _MonitorEvent;
@ -77,15 +78,6 @@ LinkProtocol::~LinkProtocol()
unregister_device_monitor(fMonitoredDevice->device, &fMonitor);
put_device_interface(fMonitoredDevice);
}
benaphore_destroy(&fLock);
}
status_t
LinkProtocol::InitCheck() const
{
return fLock.sem >= 0 && fFifo.InitCheck();
}
@ -127,26 +119,24 @@ LinkProtocol::ReadData(size_t numBytes, uint32 flags, net_buffer **_buffer)
{
BenaphoreLocker _(fLock);
bigtime_t timeout = socket->receive.timeout;
bool clone = flags & MSG_PEEK;
bigtime_t timeout = _SocketTimeout(flags);
if (timeout == 0)
flags |= MSG_DONTWAIT;
else if (timeout != B_INFINITE_TIMEOUT)
timeout += system_time();
while (fFifo.IsEmpty()) {
bool waited = false;
while (_IsEmpty()) {
if (fMonitoredDevice == NULL)
return ENODEV;
status_t status = B_WOULD_BLOCK;
if ((flags & MSG_DONTWAIT) == 0)
status = fFifo.Wait(&fLock, timeout);
status_t status = _Wait(timeout);
if (status < B_OK)
return status;
waited = true;
}
*_buffer = fFifo.Dequeue(flags & MSG_PEEK);
*_buffer = _Dequeue(clone);
if (clone && waited)
_NotifyOneReader(false);
return *_buffer ? B_OK : B_NO_MEMORY;
}
@ -157,7 +147,7 @@ LinkProtocol::ReadAvail() const
BenaphoreLocker _(fLock);
if (fMonitoredDevice == NULL)
return ENODEV;
return fFifo.current_bytes;
return fCurrentBytes;
}
@ -176,18 +166,10 @@ LinkProtocol::_Unregister()
}
status_t
LinkProtocol::_Enqueue(net_buffer *buffer)
{
BenaphoreLocker _(fLock);
return fFifo.EnqueueAndNotify(buffer, socket, B_SELECT_READ);
}
status_t
LinkProtocol::_MonitorData(net_device_monitor *monitor, net_buffer *packet)
{
return ((LinkProtocol *)monitor->cookie)->_Enqueue(packet);
return ((LinkProtocol *)monitor->cookie)->EnqueueClone(packet);
}
@ -200,8 +182,8 @@ LinkProtocol::_MonitorEvent(net_device_monitor *monitor, int32 event)
BenaphoreLocker _(protocol->fLock);
protocol->_Unregister();
if (protocol->fFifo.IsEmpty()) {
protocol->fFifo.WakeAll();
if (protocol->_IsEmpty()) {
protocol->WakeAll();
notify_socket(protocol->socket, B_SELECT_READ, ENODEV);
}
}
@ -214,7 +196,7 @@ LinkProtocol::_MonitorEvent(net_device_monitor *monitor, int32 event)
net_protocol *
link_init_protocol(net_socket *socket)
{
LinkProtocol *protocol = new (std::nothrow) LinkProtocol();
LinkProtocol *protocol = new (std::nothrow) LinkProtocol(socket);
if (protocol && protocol->InitCheck() < B_OK) {
delete protocol;
return NULL;

View File

@ -888,7 +888,7 @@ stack_std_ops(int32 op, ...)
}
static net_stack_module_info sNetStackModule = {
net_stack_module_info gNetStackModule = {
{
NET_STACK_MODULE_NAME,
0,
@ -939,7 +939,7 @@ static module_info sNetStarterModule = {
};
module_info *modules[] = {
(module_info *)&sNetStackModule,
(module_info *)&gNetStackModule,
(module_info *)&sNetStarterModule,
(module_info *)&gNetBufferModule,
(module_info *)&gNetSocketModule,

View File

@ -14,10 +14,12 @@
#include <net_datalink_protocol.h>
#include <net_protocol.h>
#include <net_socket.h>
#include <net_stack.h>
#define NET_STARTER_MODULE_NAME "network/stack/starter/v1"
extern net_stack_module_info gNetStackModule;
extern net_buffer_module_info gNetBufferModule;
extern net_socket_module_info gNetSocketModule;
extern net_datalink_module_info gNetDatalinkModule;