From af66203031e425c058de3a107ee547cb32053796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 9 Jul 2011 13:28:51 +0000 Subject: [PATCH] * Converted the hash used to the BOpenHashTable instead of khash - basically just applied r38391 to the IPv6 code (no time to resolve the TODO, and put that into a shared class). * Fixed failure on init handling. * Not tested, but should work at least better than before, as the hashtable has never been initialized before... * This closes bug #7795. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42399 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/network/protocols/ipv6/ipv6.cpp | 115 +++++++++++------- 1 file changed, 70 insertions(+), 45 deletions(-) diff --git a/src/add-ons/kernel/network/protocols/ipv6/ipv6.cpp b/src/add-ons/kernel/network/protocols/ipv6/ipv6.cpp index 452138747c..d5af3d3e60 100644 --- a/src/add-ons/kernel/network/protocols/ipv6/ipv6.cpp +++ b/src/add-ons/kernel/network/protocols/ipv6/ipv6.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2011, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -77,8 +77,8 @@ typedef DoublyLinkedListKey()); + } + + bool Compare(const KeyType& key, ValueType* value) const + { + const ipv6_packet_key& packetKey = value->Key(); + + return packetKey.id == key.id + && packetKey.source == key.source + && packetKey.destination == key.destination + && packetKey.protocol == key.protocol; + } + + ValueType*& GetLink(ValueType* value) const + { + return value->HashTableLink(); + } +}; + +typedef BOpenHashTable FragmentTable; + + class RawSocket : public DoublyLinkedListLinkImpl, public DatagramSocket<> { public: @@ -177,7 +210,7 @@ static net_socket_module_info* sSocketModule; static RawSocketList sRawSockets; static mutex sRawSocketsLock; static mutex sFragmentLock; -static hash_table* sFragmentHash; +static FragmentTable sFragmentHash; static int32 sFragmentID; static mutex sMulticastGroupsLock; @@ -222,7 +255,7 @@ IPv6Header::GetHeaderOffset(net_buffer* buffer, uint32 headerCode) const return 0; } - // the general transport layer header case + // the general transport layer header case buffer->protocol = next; return offset; } @@ -241,8 +274,8 @@ RawSocket::RawSocket(net_socket* socket) FragmentPacket::FragmentPacket(const ipv6_packet_key &key) : fKey(key), - fReceivedLastFragment(false), - fBytesLeft(IPV6_MAXPACKET) + fBytesLeft(IPV6_MAXPACKET), + fReceivedLastFragment(false) { gStackModule->init_timer(&fTimer, FragmentPacket::StaleTimer, this); } @@ -296,6 +329,9 @@ FragmentPacket::AddFragment(uint16 start, uint16 end, net_buffer* buffer, return B_OK; } + fIndex = buffer->index; + // adopt the buffer's device index + TRACE(" previous: %p, next: %p", previous, next); // If we have parts of the data already, truncate as needed @@ -423,33 +459,13 @@ FragmentPacket::Reassemble(net_buffer* to) if (buffer != to) panic("ipv6 packet reassembly did not work correctly."); + to->index = fIndex; + // reset the buffer's device index + return B_OK; } -int -FragmentPacket::Compare(void* _packet, const void* _key) -{ - const ipv6_packet_key* key = (ipv6_packet_key*)_key; - ipv6_packet_key* packetKey = &((FragmentPacket*)_packet)->fKey; - - return memcmp(packetKey, key, sizeof(ipv6_packet_key)); -} - - -uint32 -FragmentPacket::Hash(void* _packet, const void* _key, uint32 range) -{ - const struct ipv6_packet_key* key = (struct ipv6_packet_key*)_key; - FragmentPacket* packet = (FragmentPacket*)_packet; - if (packet != NULL) - key = &packet->fKey; - - return jenkins_hashword((const uint32*)key, - sizeof(ipv6_packet_key) / sizeof(uint32), 0); -} - - /*static*/ void FragmentPacket::StaleTimer(struct net_timer* timer, void* data) { @@ -457,7 +473,7 @@ FragmentPacket::StaleTimer(struct net_timer* timer, void* data) TRACE("Assembling FragmentPacket %p timed out!", packet); MutexLocker locker(&sFragmentLock); - hash_remove(sFragmentHash, packet); + sFragmentHash.Remove(packet); locker.Unlock(); if (!packet->fFragments.IsEmpty()) { @@ -529,7 +545,7 @@ reassemble_fragments(const IPv6Header &header, net_buffer** _buffer, uint16 offs // TODO: Make locking finer grained. MutexLocker locker(&sFragmentLock); - FragmentPacket* packet = (FragmentPacket*)hash_lookup(sFragmentHash, &key); + FragmentPacket* packet = sFragmentHash.Lookup(key); if (packet == NULL) { // New fragment packet packet = new (std::nothrow) FragmentPacket(key); @@ -537,7 +553,7 @@ reassemble_fragments(const IPv6Header &header, net_buffer** _buffer, uint16 offs return B_NO_MEMORY; // add packet to hash - status = hash_insert(sFragmentHash, packet); + status = sFragmentHash.Insert(packet); if (status != B_OK) { delete packet; return status; @@ -560,7 +576,7 @@ reassemble_fragments(const IPv6Header &header, net_buffer** _buffer, uint16 offs return status; if (packet->IsComplete()) { - hash_remove(sFragmentHash, packet); + sFragmentHash.Remove(packet); // no matter if reassembling succeeds, we won't need this packet // anymore @@ -629,7 +645,7 @@ send_fragments(ipv6_protocol* protocol, struct net_route* route, bool lastFragment = bytesLeft == 0; bufferHeader->header.ip6_nxt = IPPROTO_FRAGMENT; - bufferHeader->header.ip6_plen = + bufferHeader->header.ip6_plen = htons(fragmentLength + extensionHeadersLength); bufferHeader.Sync(); @@ -1619,12 +1635,17 @@ init_ipv6() sMulticastState = new MulticastState(); if (sMulticastState == NULL) { status = B_NO_MEMORY; - goto err; + goto err1; } status = sMulticastState->Init(); if (status != B_OK) - goto err; + goto err2; + + new (&sFragmentHash) FragmentTable(); + status = sFragmentHash.Init(256); + if (status != B_OK) + goto err3; new (&sRawSockets) RawSocketList; // static initializers do not work in the kernel, @@ -1634,18 +1655,21 @@ init_ipv6() status = gStackModule->register_domain_protocols(AF_INET6, SOCK_RAW, 0, NET_IPV6_MODULE_NAME, NULL); if (status != B_OK) - goto err; + goto err3; status = gStackModule->register_domain(AF_INET6, "internet6", &gIPv6Module, &gIPv6AddressModule, &sDomain); if (status != B_OK) - goto err; + goto err3; TRACE("init_ipv6: OK"); return B_OK; -err: +err3: + sFragmentHash.~FragmentTable(); +err2: delete sMulticastState; +err1: mutex_destroy(&sReceivingProtocolLock); mutex_destroy(&sMulticastGroupsLock); mutex_destroy(&sRawSocketsLock); @@ -1665,6 +1689,7 @@ uninit_ipv6() gStackModule->put_domain_receiving_protocol(sDomain, i); } + sFragmentHash.~FragmentTable(); delete sMulticastState; gStackModule->unregister_domain(sDomain);