mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-11 11:18:40 +00:00
136 lines
2.9 KiB
C
136 lines
2.9 KiB
C
/**
|
|
* Jingga
|
|
*
|
|
* @copyright Jingga
|
|
* @license OMS License 2.0
|
|
* @version 1.0.0
|
|
* @link https://jingga.app
|
|
*/
|
|
#ifndef TOS_NETWORK_PACKET_CACHE_H
|
|
#define TOS_NETWORK_PACKET_CACHE_H
|
|
|
|
#include "../../memory/RingMemory.h"
|
|
#include "../../memory/BufferMemory.h"
|
|
|
|
#if _WIN32
|
|
#include <winsock2.h>
|
|
#include <Ws2ipdef.h>
|
|
#include <windows.h>
|
|
#else
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#endif
|
|
|
|
struct PacketCache {
|
|
sockaddr_in6 addr;
|
|
|
|
int last_received;
|
|
int last_sent;
|
|
|
|
RingMemory packets_received;
|
|
RingMemory packets_sent;
|
|
|
|
int packets_received_ack[64];
|
|
int packets_sent_ack[64];
|
|
};
|
|
|
|
struct PacketCacheHashEntry {
|
|
in6_addr* key;
|
|
PacketCache* value;
|
|
PacketCacheHashEntry* next;
|
|
};
|
|
|
|
struct PacketCacheHashTable {
|
|
uint32 size;
|
|
PacketCacheHashEntry** entries;
|
|
|
|
// BufferMemory for PacketCacheHashEntry NOT PacketCache
|
|
BufferMemory buf;
|
|
};
|
|
|
|
uint32 hash_ipv6_address(uint32 hashmap_size, sockaddr_in6 *addr) {
|
|
uint32 hash_val = addr->sin6_addr;
|
|
|
|
hash_val = ((hash_val >> 16) ^ hash_val) * 0x45d9f3b;
|
|
hash_val = ((hash_val >> 16) ^ hash_val) * 0x45d9f3b;
|
|
hash_val = (hash_val >> 16) ^ hash_val;
|
|
|
|
return hash_val % hashmap_size;
|
|
}
|
|
|
|
PacketCache* hash_packet_cache_get(PacketCacheHashTable* ht, sockaddr_in6* addr) {
|
|
uint32 index = hash_ipv6_address(ht->size, addr);
|
|
|
|
PacketCacheHashEntry* entry;
|
|
if (!(entry = ht->entries[index])) {
|
|
return NULL;
|
|
}
|
|
|
|
bool no_match;
|
|
while ((no_match = (memcmp(&addr->sin6_addr, entry->key, sizeof(in6_addr)) != 0))
|
|
&& entry->next != NULL
|
|
) {
|
|
entry = entry->next;
|
|
}
|
|
|
|
if (no_match) {
|
|
return NULL;
|
|
}
|
|
|
|
return entry->value;
|
|
}
|
|
|
|
PacketCacheHashEntry* hash_packet_cache_insert(PacketCacheHashTable* ht, sockaddr_in6* addr, PacketCache* value) {
|
|
uint32 index = hash_ipv6_address(ht->size, addr);
|
|
|
|
PacketCacheHashEntry* element = (PacketCacheHashEntry *) buffer_find_free(&ht->buf);
|
|
element->key = &value->addr.sin6_addr;
|
|
element->value = value;
|
|
element->next = NULL;
|
|
|
|
PacketCacheHashEntry* entry = ht->entries[index];
|
|
if (entry == NULL) {
|
|
ht->entries[index] = element;
|
|
|
|
return element;
|
|
}
|
|
|
|
while (entry->next != NULL) {
|
|
entry = entry->next;
|
|
}
|
|
|
|
entry->next = element;
|
|
|
|
return element;
|
|
}
|
|
|
|
void hash_packet_cache_remove(PacketCacheHashTable* ht, sockaddr_in6* addr) {
|
|
uint32 index = hash_ipv6_address(ht->size, addr);
|
|
|
|
PacketCacheHashEntry* entry;
|
|
if (!(entry = ht->entries[index])) {
|
|
return;
|
|
}
|
|
|
|
PacketCacheHashEntry* prev = NULL;
|
|
|
|
bool no_match = false;
|
|
while (entry && (no_match = (memcmp(&addr->sin6_addr, entry->key, sizeof(in6_addr)) != 0))) {
|
|
prev = entry;
|
|
entry = entry->next;
|
|
}
|
|
|
|
if (no_match) {
|
|
return;
|
|
}
|
|
|
|
if (!prev) {
|
|
ht->entries[index] = NULL;
|
|
|
|
return;
|
|
}
|
|
|
|
prev->next = NULL;
|
|
}
|
|
|
|
#endif |