* Now sets the net_buffer::index field before forwarding a buffer to the next

layer.
* Converted the hash used to the BOpenHashTable instead of khash.
* Fixed remaining GCC4 warnings.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38391 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2010-08-27 10:51:39 +00:00
parent 62d3dbd618
commit 8402e1f46d
@@ -22,7 +22,6 @@
#include <KernelExport.h> #include <KernelExport.h>
#include <util/AutoLock.h> #include <util/AutoLock.h>
#include <util/list.h> #include <util/list.h>
#include <util/khash.h>
#include <util/DoublyLinkedList.h> #include <util/DoublyLinkedList.h>
#include <util/MultiHashTable.h> #include <util/MultiHashTable.h>
@@ -68,6 +67,7 @@ struct ipv4_packet_key {
uint8 protocol; uint8 protocol;
}; };
class FragmentPacket { class FragmentPacket {
public: public:
FragmentPacket(const ipv4_packet_key& key); FragmentPacket(const ipv4_packet_key& key);
@@ -81,16 +81,15 @@ public:
{ return fReceivedLastFragment { return fReceivedLastFragment
&& fBytesLeft == 0; } && fBytesLeft == 0; }
static uint32 Hash(void* _packet, const void* _key, const ipv4_packet_key& Key() const { return fKey; }
uint32 range); FragmentPacket*& HashTableLink() { return fNext; }
static int Compare(void* _packet, const void* _key);
static int32 NextOffset()
{ return offsetof(FragmentPacket, fNext); }
static void StaleTimer(struct net_timer* timer, void* data); static void StaleTimer(struct net_timer* timer, void* data);
private: private:
FragmentPacket* fNext; FragmentPacket* fNext;
struct ipv4_packet_key fKey; struct ipv4_packet_key fKey;
uint32 fIndex;
bool fReceivedLastFragment; bool fReceivedLastFragment;
int32 fBytesLeft; int32 fBytesLeft;
FragmentList fFragments; FragmentList fFragments;
@@ -98,6 +97,39 @@ private:
}; };
struct FragmentHashDefinition {
typedef ipv4_packet_key KeyType;
typedef FragmentPacket ValueType;
size_t HashKey(const KeyType& key) const
{
return (key.source ^ key.destination ^ key.protocol ^ key.id);
}
size_t Hash(ValueType* value) const
{
return HashKey(value->Key());
}
bool Compare(const KeyType& key, ValueType* value) const
{
const ipv4_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<FragmentHashDefinition, false, true> FragmentTable;
class RawSocket class RawSocket
: public DoublyLinkedListLinkImpl<RawSocket>, public DatagramSocket<> { : public DoublyLinkedListLinkImpl<RawSocket>, public DatagramSocket<> {
public: public:
@@ -167,7 +199,7 @@ static int32 sPacketID;
static RawSocketList sRawSockets; static RawSocketList sRawSockets;
static mutex sRawSocketsLock; static mutex sRawSocketsLock;
static mutex sFragmentLock; static mutex sFragmentLock;
static hash_table* sFragmentHash; static FragmentTable sFragmentHash;
static mutex sMulticastGroupsLock; static mutex sMulticastGroupsLock;
typedef MultiHashTable<MulticastStateHash> MulticastState; typedef MultiHashTable<MulticastStateHash> MulticastState;
@@ -199,9 +231,10 @@ RawSocket::RawSocket(net_socket* socket)
// #pragma mark - // #pragma mark -
FragmentPacket::FragmentPacket(const ipv4_packet_key &key) FragmentPacket::FragmentPacket(const ipv4_packet_key& key)
: :
fKey(key), fKey(key),
fIndex(0),
fReceivedLastFragment(false), fReceivedLastFragment(false),
fBytesLeft(IP_MAXPACKET) fBytesLeft(IP_MAXPACKET)
{ {
@@ -257,6 +290,9 @@ FragmentPacket::AddFragment(uint16 start, uint16 end, net_buffer* buffer,
return B_OK; return B_OK;
} }
fIndex = buffer->index;
// adopt the buffer's device index
TRACE(" previous: %p, next: %p", previous, next); TRACE(" previous: %p, next: %p", previous, next);
// If we have parts of the data already, truncate as needed // If we have parts of the data already, truncate as needed
@@ -384,38 +420,13 @@ FragmentPacket::Reassemble(net_buffer* to)
if (buffer != to) if (buffer != to)
panic("ipv4 packet reassembly did not work correctly."); panic("ipv4 packet reassembly did not work correctly.");
to->index = fIndex;
// reset the buffer's device index
return B_OK; return B_OK;
} }
int
FragmentPacket::Compare(void* _packet, const void* _key)
{
const ipv4_packet_key* key = (ipv4_packet_key*)_key;
ipv4_packet_key* packetKey = &((FragmentPacket*)_packet)->fKey;
if (packetKey->id == key->id
&& packetKey->source == key->source
&& packetKey->destination == key->destination
&& packetKey->protocol == key->protocol)
return 0;
return 1;
}
uint32
FragmentPacket::Hash(void* _packet, const void* _key, uint32 range)
{
const struct ipv4_packet_key* key = (struct ipv4_packet_key*)_key;
FragmentPacket* packet = (FragmentPacket*)_packet;
if (packet != NULL)
key = &packet->fKey;
return (key->source ^ key->destination ^ key->protocol ^ key->id) % range;
}
/*static*/ void /*static*/ void
FragmentPacket::StaleTimer(struct net_timer* timer, void* data) FragmentPacket::StaleTimer(struct net_timer* timer, void* data)
{ {
@@ -423,7 +434,7 @@ FragmentPacket::StaleTimer(struct net_timer* timer, void* data)
TRACE("Assembling FragmentPacket %p timed out!", packet); TRACE("Assembling FragmentPacket %p timed out!", packet);
MutexLocker locker(&sFragmentLock); MutexLocker locker(&sFragmentLock);
hash_remove(sFragmentHash, packet); sFragmentHash.Remove(packet);
locker.Unlock(); locker.Unlock();
if (!packet->fFragments.IsEmpty()) { if (!packet->fFragments.IsEmpty()) {
@@ -529,7 +540,7 @@ reassemble_fragments(const ipv4_header &header, net_buffer** _buffer)
// TODO: Make locking finer grained. // TODO: Make locking finer grained.
MutexLocker locker(&sFragmentLock); MutexLocker locker(&sFragmentLock);
FragmentPacket* packet = (FragmentPacket*)hash_lookup(sFragmentHash, &key); FragmentPacket* packet = sFragmentHash.Lookup(key);
if (packet == NULL) { if (packet == NULL) {
// New fragment packet // New fragment packet
packet = new (std::nothrow) FragmentPacket(key); packet = new (std::nothrow) FragmentPacket(key);
@@ -537,7 +548,7 @@ reassemble_fragments(const ipv4_header &header, net_buffer** _buffer)
return B_NO_MEMORY; return B_NO_MEMORY;
// add packet to hash // add packet to hash
status = hash_insert(sFragmentHash, packet); status = sFragmentHash.Insert(packet);
if (status != B_OK) { if (status != B_OK) {
delete packet; delete packet;
return status; return status;
@@ -561,7 +572,7 @@ reassemble_fragments(const ipv4_header &header, net_buffer** _buffer)
return status; return status;
if (packet->IsComplete()) { if (packet->IsComplete()) {
hash_remove(sFragmentHash, packet); sFragmentHash.Remove(packet);
// no matter if reassembling succeeds, we won't need this packet // no matter if reassembling succeeds, we won't need this packet
// anymore // anymore
@@ -969,7 +980,7 @@ ipv4_generic_delta_membership(ipv4_protocol* protocol, int option,
const sockaddr_storage* _sourceAddr) const sockaddr_storage* _sourceAddr)
{ {
if (_groupAddr->ss_family != AF_INET if (_groupAddr->ss_family != AF_INET
|| _sourceAddr != NULL && _sourceAddr->ss_family != AF_INET) || (_sourceAddr != NULL && _sourceAddr->ss_family != AF_INET))
return B_BAD_VALUE; return B_BAD_VALUE;
const in_addr* groupAddr = &((const sockaddr_in*)_groupAddr)->sin_addr; const in_addr* groupAddr = &((const sockaddr_in*)_groupAddr)->sin_addr;
@@ -1822,9 +1833,9 @@ init_ipv4()
if (status != B_OK) if (status != B_OK)
goto err5; goto err5;
sFragmentHash = hash_init(MAX_HASH_FRAGMENTS, FragmentPacket::NextOffset(), new (&sFragmentHash) FragmentTable();
&FragmentPacket::Compare, &FragmentPacket::Hash); status = sFragmentHash.Init(256);
if (sFragmentHash == NULL) if (status != B_OK)
goto err5; goto err5;
new (&sRawSockets) RawSocketList; new (&sRawSockets) RawSocketList;
@@ -1848,7 +1859,7 @@ init_ipv4()
return B_OK; return B_OK;
err6: err6:
hash_uninit(sFragmentHash); sFragmentHash.~FragmentTable();
err5: err5:
delete sMulticastState; delete sMulticastState;
err4: err4:
@@ -1877,7 +1888,7 @@ uninit_ipv4()
mutex_unlock(&sReceivingProtocolLock); mutex_unlock(&sReceivingProtocolLock);
delete sMulticastState; delete sMulticastState;
hash_uninit(sFragmentHash); sFragmentHash.~FragmentTable();
mutex_destroy(&sMulticastGroupsLock); mutex_destroy(&sMulticastGroupsLock);
mutex_destroy(&sFragmentLock); mutex_destroy(&sFragmentLock);