This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
stellar-stellar/infra/packet_manager/packet_dabloom.c
2024-11-07 19:09:26 +08:00

132 lines
3.6 KiB
C

#include "dablooms.h"
#include "packet_dabloom.h"
#include "packet_internal.h"
struct packet_key
{
// TCP or UDP
uint32_t seq; // network order
uint32_t ack; // network order
uint16_t src_port; // network order
uint16_t dst_port; // network order
uint16_t l4_checksum; // network order
// IPv4
uint16_t ip_id; // network order
uint32_t src_addr; // network order
uint32_t dst_addr; // network order
} __attribute__((__packed__));
struct packet_dabloom
{
struct expiry_dablooms_handle *dablooms;
};
/******************************************************************************
* Private API
******************************************************************************/
// return 0: success
// reutrn -1: error
static inline int packet_key_get(const struct packet *packet, struct packet_key *key)
{
const struct layer_internal *ip_layer = packet_get_innermost_layer(packet, LAYER_PROTO_IPV4);
const struct layer_internal *tcp_layer = packet_get_innermost_layer(packet, LAYER_PROTO_TCP);
const struct layer_internal *udp_layer = packet_get_innermost_layer(packet, LAYER_PROTO_UDP);
if (ip_layer == NULL || (tcp_layer == NULL && udp_layer == NULL))
{
return -1;
}
memset(key, 0, sizeof(struct packet_key));
const struct ip *iphdr = (const struct ip *)ip_layer->hdr_ptr;
key->ip_id = iphdr->ip_id;
key->src_addr = iphdr->ip_src.s_addr;
key->dst_addr = iphdr->ip_dst.s_addr;
if (tcp_layer)
{
const struct tcphdr *tcphdr = (const struct tcphdr *)tcp_layer->hdr_ptr;
key->seq = tcphdr->th_seq;
key->ack = tcphdr->th_ack;
key->src_port = tcphdr->th_sport;
key->dst_port = tcphdr->th_dport;
key->l4_checksum = tcphdr->th_sum;
}
else
{
const struct udphdr *udphdr = (const struct udphdr *)udp_layer->hdr_ptr;
key->src_port = udphdr->uh_sport;
key->dst_port = udphdr->uh_dport;
key->l4_checksum = udphdr->uh_sum;
}
return 0;
}
/******************************************************************************
* Public API
******************************************************************************/
struct packet_dabloom *packet_dabloom_new(uint32_t capacity, uint32_t timeout, double error_rate, uint64_t now)
{
struct packet_dabloom *pkt_dab = (struct packet_dabloom *)calloc(1, sizeof(struct packet_dabloom));
if (pkt_dab == NULL)
{
return NULL;
}
pkt_dab->dablooms = expiry_dablooms_new(capacity, error_rate, now, timeout);
if (pkt_dab->dablooms == NULL)
{
free(pkt_dab);
return NULL;
}
return pkt_dab;
}
void packet_dabloom_free(struct packet_dabloom *pkt_dab)
{
if (pkt_dab)
{
if (pkt_dab->dablooms)
{
expiry_dablooms_free(pkt_dab->dablooms);
pkt_dab->dablooms = NULL;
}
free(pkt_dab);
pkt_dab = NULL;
}
}
// return 1: found
// reutrn 0: no found
int packet_dabloom_lookup(struct packet_dabloom *pkt_dab, const struct packet *packet, uint64_t now)
{
struct packet_key key;
if (packet_key_get(packet, &key) == -1)
{
return 0;
}
if (expiry_dablooms_search(pkt_dab->dablooms, (const char *)&key, sizeof(struct packet_key), now) == 1)
{
return 1;
}
return 0;
}
void packet_dabloom_add(struct packet_dabloom *pkt_dab, const struct packet *packet, uint64_t now)
{
struct packet_key key;
if (packet_key_get(packet, &key) == -1)
{
return;
}
expiry_dablooms_add(pkt_dab->dablooms, (const char *)&key, sizeof(struct packet_key), now);
}