The IPv4 protocol now stores all domain receiving protocols, and only put them away on uninit.

This should speed up packet retrieval a lot.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19811 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2007-01-15 14:22:31 +00:00
parent 235a50037c
commit ab4048488d

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.
*
* Authors:
@ -148,6 +148,8 @@ static RawSocketList sRawSockets;
static benaphore sRawSocketsLock;
static benaphore sFragmentLock;
static hash_table *sFragmentHash;
static net_protocol_module_info *sReceivingProtocol[256];
static benaphore sReceivingProtocolLock;
RawSocket::RawSocket(net_socket *socket)
@ -661,6 +663,26 @@ raw_receive_data(net_buffer *buffer)
}
static net_protocol_module_info *
receiving_protocol(uint8 protocol)
{
net_protocol_module_info *module = sReceivingProtocol[protocol];
if (module != NULL)
return module;
BenaphoreLocker locker(sReceivingProtocolLock);
module = sReceivingProtocol[protocol];
if (module != NULL)
return module;
if (sStackModule->get_domain_receiving_protocol(sDomain, protocol, &module) == B_OK)
sReceivingProtocol[protocol] = module;
return module;
}
// #pragma mark -
@ -1126,19 +1148,13 @@ ipv4_receive_data(net_buffer *buffer)
// the header is of variable size and may include IP options
// (that we ignore for now)
// TODO: since we'll doing this for every packet, we may want to cache the module
// (and only put them when we're about to be unloaded)
net_protocol_module_info *module;
status = sStackModule->get_domain_receiving_protocol(sDomain, protocol, &module);
if (status < B_OK) {
net_protocol_module_info *module = receiving_protocol(protocol);
if (module == NULL) {
// no handler for this packet
return status;
return EAFNOSUPPORT;
}
status = module->receive_data(buffer);
sStackModule->put_domain_receiving_protocol(sDomain, protocol);
return status;
return module->receive_data(buffer);
}
@ -1183,10 +1199,14 @@ init_ipv4()
if (status < B_OK)
goto err4;
status = benaphore_init(&sReceivingProtocolLock, "IPv4 receiving protocols");
if (status < B_OK)
goto err5;
sFragmentHash = hash_init(MAX_HASH_FRAGMENTS, FragmentPacket::NextOffset(),
&FragmentPacket::Compare, &FragmentPacket::Hash);
if (sFragmentHash == NULL)
goto err5;
goto err6;
new (&sRawSockets) RawSocketList;
// static initializers do not work in the kernel,
@ -1196,17 +1216,19 @@ init_ipv4()
status = sStackModule->register_domain_protocols(AF_INET, SOCK_RAW, 0,
"network/protocols/ipv4/v1", NULL);
if (status < B_OK)
goto err6;
goto err7;
status = sStackModule->register_domain(AF_INET, "internet", &gIPv4Module,
&gIPv4AddressModule, &sDomain);
if (status < B_OK)
goto err6;
goto err7;
return B_OK;
err6:
err7:
hash_uninit(sFragmentHash);
err6:
benaphore_destroy(&sReceivingProtocolLock);
err5:
benaphore_destroy(&sFragmentLock);
err4:
@ -1224,12 +1246,23 @@ err1:
status_t
uninit_ipv4()
{
benaphore_lock(&sReceivingProtocolLock);
// 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);
}
sStackModule->unregister_domain(sDomain);
benaphore_unlock(&sReceivingProtocolLock);
hash_uninit(sFragmentHash);
benaphore_destroy(&sFragmentLock);
benaphore_destroy(&sRawSocketsLock);
benaphore_destroy(&sReceivingProtocolLock);
sStackModule->unregister_domain(sDomain);
put_module(NET_DATALINK_MODULE_NAME);
put_module(NET_BUFFER_MODULE_NAME);
put_module(NET_STACK_MODULE_NAME);