use OpenHashTable in IPv4's MulticastGroups.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20910 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
15945a11c6
commit
6b783773bf
@ -22,6 +22,7 @@
|
|||||||
#include <util/list.h>
|
#include <util/list.h>
|
||||||
#include <util/khash.h>
|
#include <util/khash.h>
|
||||||
#include <util/DoublyLinkedList.h>
|
#include <util/DoublyLinkedList.h>
|
||||||
|
#include <util/OpenHashTable.h>
|
||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
@ -128,19 +129,32 @@ public:
|
|||||||
void Remove(Link *link);
|
void Remove(Link *link);
|
||||||
bool IsEmpty() const { return fLinks.IsEmpty(); }
|
bool IsEmpty() const { return fLinks.IsEmpty(); }
|
||||||
|
|
||||||
static uint32 Hash(void *address, const void *key, uint32 range);
|
struct HashDefinition {
|
||||||
static int Compare(void *address, const void *key);
|
typedef void ParentType;
|
||||||
static int32 NextOffset() { return offsetof(MulticastGroup, fNext); }
|
typedef const in_addr KeyType;
|
||||||
|
typedef MulticastGroup ValueType;
|
||||||
|
|
||||||
static const int kMaxGroups = 64;
|
size_t HashKey(const in_addr &address) const
|
||||||
|
{ return address.s_addr; }
|
||||||
|
size_t Hash(MulticastGroup *group) const
|
||||||
|
{ return HashKey(group->fMulticastAddress); }
|
||||||
|
bool Compare(const in_addr &address, MulticastGroup *group) const
|
||||||
|
{ return group->fMulticastAddress.s_addr == address.s_addr; }
|
||||||
|
HashTableLink<MulticastGroup> *GetLink(MulticastGroup *group) const
|
||||||
|
{ return &group->fLink; }
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// for g++ 2.95
|
||||||
|
friend class HashDefinition;
|
||||||
|
|
||||||
typedef DoublyLinkedListCLink<Link> LinkLink;
|
typedef DoublyLinkedListCLink<Link> LinkLink;
|
||||||
typedef DoublyLinkedList<Link, LinkLink> Links;
|
typedef DoublyLinkedList<Link, LinkLink> Links;
|
||||||
|
|
||||||
MulticastGroup *fNext;
|
|
||||||
in_addr fMulticastAddress;
|
in_addr fMulticastAddress;
|
||||||
Links fLinks;
|
Links fLinks;
|
||||||
|
|
||||||
|
HashTableLink<MulticastGroup> fLink;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RawSocket : public DoublyLinkedListLinkImpl<RawSocket>, public DatagramSocket<> {
|
class RawSocket : public DoublyLinkedListLinkImpl<RawSocket>, public DatagramSocket<> {
|
||||||
@ -188,7 +202,8 @@ static benaphore sRawSocketsLock;
|
|||||||
static benaphore sFragmentLock;
|
static benaphore sFragmentLock;
|
||||||
static hash_table *sFragmentHash;
|
static hash_table *sFragmentHash;
|
||||||
static benaphore sMulticastGroupsLock;
|
static benaphore sMulticastGroupsLock;
|
||||||
static hash_table *sMulticastGroups;
|
typedef OpenHashTable<MulticastGroup::HashDefinition> MulticastGroups;
|
||||||
|
static MulticastGroups *sMulticastGroups;
|
||||||
static net_protocol_module_info *sReceivingProtocol[256];
|
static net_protocol_module_info *sReceivingProtocol[256];
|
||||||
static benaphore sReceivingProtocolLock;
|
static benaphore sReceivingProtocolLock;
|
||||||
|
|
||||||
@ -488,33 +503,6 @@ MulticastGroup::Remove(Link *link)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
MulticastGroup::Compare(void *_group, const void *_key)
|
|
||||||
{
|
|
||||||
MulticastGroup *group = (MulticastGroup *)_group;
|
|
||||||
|
|
||||||
return memcmp(&group->fMulticastAddress, _key, sizeof(in_addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32
|
|
||||||
MulticastGroup::Hash(void *_group, const void *_key, uint32 range)
|
|
||||||
{
|
|
||||||
const in_addr *address = (const in_addr *)_key;
|
|
||||||
if (_group != NULL)
|
|
||||||
address = &((MulticastGroup *)_group)->fMulticastAddress;
|
|
||||||
|
|
||||||
union {
|
|
||||||
in_addr_t address;
|
|
||||||
uint8 data[4];
|
|
||||||
} addr;
|
|
||||||
|
|
||||||
addr.address = address->s_addr & IN_CLASSD_HOST;
|
|
||||||
|
|
||||||
return (addr.data[0] ^ addr.data[1] ^ addr.data[2] ^ addr.data[3]) % range;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@ -714,8 +702,8 @@ deliver_multicast(net_protocol_module_info *module, net_buffer *buffer,
|
|||||||
{
|
{
|
||||||
BenaphoreLocker _(sMulticastGroupsLock);
|
BenaphoreLocker _(sMulticastGroupsLock);
|
||||||
|
|
||||||
MulticastGroup *group = (MulticastGroup *)hash_lookup(sMulticastGroups,
|
MulticastGroup *group = sMulticastGroups->Lookup(
|
||||||
&buffer->destination);
|
((sockaddr_in *)&buffer->destination)->sin_addr);
|
||||||
if (group == NULL)
|
if (group == NULL)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
@ -758,18 +746,13 @@ IPv4Multicast::JoinGroup(const in_addr &groupAddr, MulticastGroup::Link *link)
|
|||||||
{
|
{
|
||||||
BenaphoreLocker _(sMulticastGroupsLock);
|
BenaphoreLocker _(sMulticastGroupsLock);
|
||||||
|
|
||||||
MulticastGroup *group = (MulticastGroup *)hash_lookup(sMulticastGroups,
|
MulticastGroup *group = sMulticastGroups->Lookup(groupAddr);
|
||||||
&groupAddr);
|
|
||||||
if (group == NULL) {
|
if (group == NULL) {
|
||||||
group = new (std::nothrow) MulticastGroup(groupAddr);
|
group = new (std::nothrow) MulticastGroup(groupAddr);
|
||||||
if (group == NULL)
|
if (group == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
status_t status = hash_insert(sMulticastGroups, group);
|
sMulticastGroups->Insert(group);
|
||||||
if (status < B_OK) {
|
|
||||||
delete group;
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
group->Add(link);
|
group->Add(link);
|
||||||
@ -782,14 +765,13 @@ IPv4Multicast::LeaveGroup(const in_addr &groupAddr, MulticastGroup::Link *link)
|
|||||||
{
|
{
|
||||||
BenaphoreLocker _(sMulticastGroupsLock);
|
BenaphoreLocker _(sMulticastGroupsLock);
|
||||||
|
|
||||||
MulticastGroup *group = (MulticastGroup *)hash_lookup(sMulticastGroups,
|
MulticastGroup *group = sMulticastGroups->Lookup(groupAddr);
|
||||||
&groupAddr);
|
|
||||||
if (group == NULL)
|
if (group == NULL)
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
|
|
||||||
group->Remove(link);
|
group->Remove(link);
|
||||||
if (group->IsEmpty()) {
|
if (group->IsEmpty()) {
|
||||||
hash_remove(sMulticastGroups, group);
|
sMulticastGroups->Remove(group);
|
||||||
delete group;
|
delete group;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1607,12 +1589,14 @@ init_ipv4()
|
|||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto err3;
|
goto err3;
|
||||||
|
|
||||||
sMulticastGroups = hash_init(MulticastGroup::kMaxGroups,
|
sMulticastGroups = new MulticastGroups();
|
||||||
MulticastGroup::NextOffset(), &MulticastGroup::Compare,
|
|
||||||
&MulticastGroup::Hash);
|
|
||||||
if (sMulticastGroups == NULL)
|
if (sMulticastGroups == NULL)
|
||||||
goto err4;
|
goto err4;
|
||||||
|
|
||||||
|
status = sMulticastGroups->InitCheck();
|
||||||
|
if (status < B_OK)
|
||||||
|
goto err5;
|
||||||
|
|
||||||
sFragmentHash = hash_init(MAX_HASH_FRAGMENTS, FragmentPacket::NextOffset(),
|
sFragmentHash = hash_init(MAX_HASH_FRAGMENTS, FragmentPacket::NextOffset(),
|
||||||
&FragmentPacket::Compare, &FragmentPacket::Hash);
|
&FragmentPacket::Compare, &FragmentPacket::Hash);
|
||||||
if (sFragmentHash == NULL)
|
if (sFragmentHash == NULL)
|
||||||
@ -1638,7 +1622,7 @@ init_ipv4()
|
|||||||
err6:
|
err6:
|
||||||
hash_uninit(sFragmentHash);
|
hash_uninit(sFragmentHash);
|
||||||
err5:
|
err5:
|
||||||
hash_uninit(sMulticastGroups);
|
delete sMulticastGroups;
|
||||||
err4:
|
err4:
|
||||||
benaphore_destroy(&sReceivingProtocolLock);
|
benaphore_destroy(&sReceivingProtocolLock);
|
||||||
err3:
|
err3:
|
||||||
@ -1665,7 +1649,7 @@ uninit_ipv4()
|
|||||||
gStackModule->unregister_domain(sDomain);
|
gStackModule->unregister_domain(sDomain);
|
||||||
benaphore_unlock(&sReceivingProtocolLock);
|
benaphore_unlock(&sReceivingProtocolLock);
|
||||||
|
|
||||||
hash_uninit(sMulticastGroups);
|
delete sMulticastGroups;
|
||||||
hash_uninit(sFragmentHash);
|
hash_uninit(sFragmentHash);
|
||||||
|
|
||||||
benaphore_destroy(&sMulticastGroupsLock);
|
benaphore_destroy(&sMulticastGroupsLock);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user