reactor packet I/O & duplicated packet filter & evicted session filter
This commit is contained in:
@@ -4,12 +4,10 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "packet.h"
|
||||
#include "timestamp.h"
|
||||
#include "crc32_hash.h"
|
||||
#include "checksum.h"
|
||||
#include "ipv4_utils.h"
|
||||
#include "ipv6_utils.h"
|
||||
#include "packet_utils.h"
|
||||
#include "ip_reassembly.h"
|
||||
|
||||
#define IPV4_KEYLEN 1
|
||||
@@ -303,7 +301,7 @@ static inline void ip_flow_key_zero(struct ip_flow_key *key)
|
||||
|
||||
static inline void ip_frag_hdr_init(struct ip_frag_hdr *hdr, const struct packet *pkt)
|
||||
{
|
||||
struct layer_record *layer = pkt->frag_layer;
|
||||
struct layer *layer = pkt->frag_layer;
|
||||
|
||||
if (layer->type == LAYER_TYPE_IPV6)
|
||||
{
|
||||
@@ -367,7 +365,7 @@ static inline void ip_frag_pkt_free(struct ip_frag_pkt *frag)
|
||||
* ip flow
|
||||
******************************************************************************/
|
||||
|
||||
static inline void ip_flow_init(struct ip_flow *flow, const struct ip_flow_key *key)
|
||||
static inline void ip_flow_init(struct ip_flow *flow, const struct ip_flow_key *key, uint64_t now_sec)
|
||||
{
|
||||
static const struct ip_frag_pkt zero_frag = {
|
||||
.data = NULL,
|
||||
@@ -378,7 +376,7 @@ static inline void ip_flow_init(struct ip_flow *flow, const struct ip_flow_key *
|
||||
flow->lru.tqe_next = NULL;
|
||||
flow->lru.tqe_prev = NULL;
|
||||
flow->key = *key;
|
||||
flow->create_time = timestamp_get_sec();
|
||||
flow->create_time = now_sec;
|
||||
flow->expected_total_size = UINT32_MAX;
|
||||
flow->received_frag_size = 0;
|
||||
flow->next_fill_idx = IP_MIN_FRAG_NUM;
|
||||
@@ -480,11 +478,11 @@ static inline void ip_reassembly_del_flow(struct ip_reassembly *mgr, struct ip_f
|
||||
mgr->entry_used--;
|
||||
}
|
||||
|
||||
static inline void ip_reassembly_reuse_flow(struct ip_reassembly *mgr, struct ip_flow *flow, const struct ip_flow_key *key)
|
||||
static inline void ip_reassembly_reuse_flow(struct ip_reassembly *mgr, struct ip_flow *flow, const struct ip_flow_key *key, uint64_t now_sec)
|
||||
{
|
||||
ip_reassembly_del_flow(mgr, flow);
|
||||
ip_flow_free(flow);
|
||||
ip_flow_init(flow, key);
|
||||
ip_flow_init(flow, key, now_sec);
|
||||
ip_reassembly_add_flow(mgr, flow);
|
||||
}
|
||||
|
||||
@@ -493,7 +491,7 @@ static inline void ip_reassembly_reuse_flow(struct ip_reassembly *mgr, struct ip
|
||||
* free : the first empty entry in the bucket
|
||||
* expired: the first timed-out entry in the bucket
|
||||
*/
|
||||
static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const struct ip_flow_key *key, struct ip_flow **free, struct ip_flow **expired)
|
||||
static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const struct ip_flow_key *key, struct ip_flow **free, struct ip_flow **expired, uint64_t now_sec)
|
||||
{
|
||||
ip_reassembly_stat_inc(mgr, find, key);
|
||||
|
||||
@@ -522,7 +520,6 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
|
||||
struct ip_flow *empty = NULL;
|
||||
uint64_t timeout = mgr->timeout;
|
||||
uint32_t assoc = mgr->bucket_entries;
|
||||
uint64_t tms = timestamp_get_sec();
|
||||
for (uint32_t i = 0; i != assoc; i++)
|
||||
{
|
||||
if (ip_flow_key_cmp(key, &p1[i].key) == 0)
|
||||
@@ -535,7 +532,7 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
|
||||
{
|
||||
empty = (empty == NULL) ? (p1 + i) : empty;
|
||||
}
|
||||
else if (timeout + p1[i].create_time <= tms)
|
||||
else if (timeout + p1[i].create_time <= now_sec)
|
||||
{
|
||||
old = (old == NULL) ? (p1 + i) : old;
|
||||
}
|
||||
@@ -550,7 +547,7 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
|
||||
{
|
||||
empty = (empty == NULL) ? (p2 + i) : empty;
|
||||
}
|
||||
else if (timeout + p2[i].create_time <= tms)
|
||||
else if (timeout + p2[i].create_time <= now_sec)
|
||||
{
|
||||
old = (old == NULL) ? (p2 + i) : old;
|
||||
}
|
||||
@@ -561,19 +558,19 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, const struct ip_flow_key *key)
|
||||
static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, const struct ip_flow_key *key, uint64_t now_sec)
|
||||
{
|
||||
struct ip_flow *flow = NULL;
|
||||
struct ip_flow *free = NULL;
|
||||
struct ip_flow *expired = NULL;
|
||||
|
||||
flow = ip_reassembly_find_flow(mgr, key, &free, &expired);
|
||||
flow = ip_reassembly_find_flow(mgr, key, &free, &expired, now_sec);
|
||||
if (flow == NULL)
|
||||
{
|
||||
if (expired)
|
||||
{
|
||||
IP_REASSEMBLE_DEBUG1("add ip flow success: reuse expired entry", key);
|
||||
ip_reassembly_reuse_flow(mgr, expired, key);
|
||||
ip_reassembly_reuse_flow(mgr, expired, key, now_sec);
|
||||
ip_reassembly_stat_inc(mgr, timeout, key);
|
||||
|
||||
mgr->last = expired;
|
||||
@@ -583,7 +580,7 @@ static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, cons
|
||||
if (free)
|
||||
{
|
||||
IP_REASSEMBLE_DEBUG1("add ip flow success: use free entry", key);
|
||||
ip_flow_init(free, key);
|
||||
ip_flow_init(free, key, now_sec);
|
||||
ip_reassembly_add_flow(mgr, free);
|
||||
|
||||
mgr->last = free;
|
||||
@@ -598,10 +595,10 @@ static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, cons
|
||||
else
|
||||
{
|
||||
// expired
|
||||
if (mgr->timeout + flow->create_time <= timestamp_get_sec())
|
||||
if (mgr->timeout + flow->create_time <= now_sec)
|
||||
{
|
||||
IP_REASSEMBLE_DEBUG1("add ip flow success: reuse expired entry", key);
|
||||
ip_reassembly_reuse_flow(mgr, flow, key);
|
||||
ip_reassembly_reuse_flow(mgr, flow, key, now_sec);
|
||||
ip_reassembly_stat_inc(mgr, timeout, key);
|
||||
|
||||
mgr->last = flow;
|
||||
@@ -817,14 +814,13 @@ void ip_reassembly_free(struct ip_reassembly *mgr)
|
||||
}
|
||||
}
|
||||
|
||||
void ip_reassembly_expire(struct ip_reassembly *mgr)
|
||||
void ip_reassembly_expire(struct ip_reassembly *mgr, uint64_t now_sec)
|
||||
{
|
||||
struct ip_flow *flow = NULL;
|
||||
uint64_t curr_ts = timestamp_get_sec();
|
||||
uint64_t timeout = mgr->timeout;
|
||||
|
||||
TAILQ_FOREACH(flow, &mgr->lru, lru)
|
||||
if (timeout + flow->create_time <= curr_ts)
|
||||
if (timeout + flow->create_time <= now_sec)
|
||||
{
|
||||
IP_REASSEMBLE_DEBUG1("expire ip flow: discarding old fragmented packets", &flow->key);
|
||||
ip_reassembly_del_flow(mgr, flow);
|
||||
@@ -833,34 +829,6 @@ void ip_reassembly_expire(struct ip_reassembly *mgr)
|
||||
}
|
||||
}
|
||||
|
||||
void ip_reassembly_print_stat(struct ip_reassembly *mgr)
|
||||
{
|
||||
if (mgr)
|
||||
{
|
||||
IP_REASSEMBLE_DEBUG("ip4_flow_find : %lu", mgr->stat.ip4_flow_find);
|
||||
IP_REASSEMBLE_DEBUG("ip4_flow_add : %lu", mgr->stat.ip4_flow_add);
|
||||
IP_REASSEMBLE_DEBUG("ip4_flow_del : %lu", mgr->stat.ip4_flow_del);
|
||||
IP_REASSEMBLE_DEBUG("ip4_flow_timeout : %lu", mgr->stat.ip4_flow_timeout);
|
||||
IP_REASSEMBLE_DEBUG("ip4_flow_fail_no_space : %lu", mgr->stat.ip4_flow_fail_no_space);
|
||||
IP_REASSEMBLE_DEBUG("ip4_flow_fail_overlap : %lu", mgr->stat.ip4_flow_fail_overlap);
|
||||
IP_REASSEMBLE_DEBUG("ip4_flow_fail_many_frag : %lu", mgr->stat.ip4_flow_fail_many_frag);
|
||||
IP_REASSEMBLE_DEBUG("ip4_flow_fail_invalid_length : %lu", mgr->stat.ip4_flow_fail_invalid_length);
|
||||
IP_REASSEMBLE_DEBUG("ip4_flow_bypass_dup_fist_frag : %lu", mgr->stat.ip4_flow_bypass_dup_fist_frag);
|
||||
IP_REASSEMBLE_DEBUG("ip4_flow_bypass_dup_last_frag : %lu", mgr->stat.ip4_flow_bypass_dup_last_frag);
|
||||
|
||||
IP_REASSEMBLE_DEBUG("ip6_flow_find : %lu", mgr->stat.ip6_flow_find);
|
||||
IP_REASSEMBLE_DEBUG("ip6_flow_add : %lu", mgr->stat.ip6_flow_add);
|
||||
IP_REASSEMBLE_DEBUG("ip6_flow_del : %lu", mgr->stat.ip6_flow_del);
|
||||
IP_REASSEMBLE_DEBUG("ip6_flow_timeout : %lu", mgr->stat.ip6_flow_timeout);
|
||||
IP_REASSEMBLE_DEBUG("ip6_flow_fail_no_space : %lu", mgr->stat.ip6_flow_fail_no_space);
|
||||
IP_REASSEMBLE_DEBUG("ip6_flow_fail_overlap : %lu", mgr->stat.ip6_flow_fail_overlap);
|
||||
IP_REASSEMBLE_DEBUG("ip6_flow_fail_many_frag : %lu", mgr->stat.ip6_flow_fail_many_frag);
|
||||
IP_REASSEMBLE_DEBUG("ip6_flow_fail_invalid_length : %lu", mgr->stat.ip6_flow_fail_invalid_length);
|
||||
IP_REASSEMBLE_DEBUG("ip6_flow_bypass_dup_fist_frag : %lu", mgr->stat.ip6_flow_bypass_dup_fist_frag);
|
||||
IP_REASSEMBLE_DEBUG("ip6_flow_bypass_dup_last_frag : %lu", mgr->stat.ip6_flow_bypass_dup_last_frag);
|
||||
}
|
||||
}
|
||||
|
||||
struct ip_reassembly_stat *ip_reassembly_get_stat(struct ip_reassembly *mgr)
|
||||
{
|
||||
if (mgr)
|
||||
@@ -878,7 +846,7 @@ struct ip_reassembly_stat *ip_reassembly_get_stat(struct ip_reassembly *mgr)
|
||||
* The returned packet should be freed by calling the packet_free() function
|
||||
*/
|
||||
|
||||
struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt)
|
||||
struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now_sec)
|
||||
{
|
||||
struct packet *pkt1;
|
||||
struct packet *pkt2;
|
||||
@@ -888,7 +856,7 @@ struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct pack
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct layer_record *layer = pkt->frag_layer;
|
||||
const struct layer *layer = pkt->frag_layer;
|
||||
if (layer == NULL)
|
||||
{
|
||||
return NULL;
|
||||
@@ -896,10 +864,10 @@ struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct pack
|
||||
|
||||
if (layer->type == LAYER_TYPE_IPV4)
|
||||
{
|
||||
pkt1 = ipv4_reassembly_packet(mgr, pkt);
|
||||
pkt1 = ipv4_reassembly_packet(mgr, pkt, now_sec);
|
||||
if (pkt1 && pkt1->frag_layer)
|
||||
{
|
||||
pkt2 = ip_reassembly_packet(mgr, pkt1);
|
||||
pkt2 = ip_reassembly_packet(mgr, pkt1, now_sec);
|
||||
packet_free(pkt1);
|
||||
return pkt2;
|
||||
}
|
||||
@@ -908,10 +876,10 @@ struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct pack
|
||||
}
|
||||
else if (layer->type == LAYER_TYPE_IPV6)
|
||||
{
|
||||
pkt1 = ipv6_reassembly_packet(mgr, pkt);
|
||||
pkt1 = ipv6_reassembly_packet(mgr, pkt, now_sec);
|
||||
if (pkt1 && pkt1->frag_layer)
|
||||
{
|
||||
pkt2 = ip_reassembly_packet(mgr, pkt1);
|
||||
pkt2 = ip_reassembly_packet(mgr, pkt1, now_sec);
|
||||
packet_free(pkt1);
|
||||
return pkt2;
|
||||
}
|
||||
@@ -924,9 +892,9 @@ struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct pack
|
||||
}
|
||||
}
|
||||
|
||||
struct packet *ipv4_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt)
|
||||
struct packet *ipv4_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now_sec)
|
||||
{
|
||||
const struct layer_record *layer = pkt->frag_layer;
|
||||
const struct layer *layer = pkt->frag_layer;
|
||||
const struct ip *hdr = (const struct ip *)layer->hdr_ptr;
|
||||
uint16_t frag_len = ipv4_hdr_get_total_len(hdr) - ipv4_hdr_get_hdr_len(hdr);
|
||||
if (frag_len > layer->pld_len)
|
||||
@@ -943,7 +911,7 @@ struct packet *ipv4_reassembly_packet(struct ip_reassembly *mgr, const struct pa
|
||||
key.ip_id = ipv4_hdr_get_ipid(hdr);
|
||||
key.proto = ipv4_hdr_get_proto(hdr);
|
||||
|
||||
struct ip_flow *flow = ip_reassembly_update_flow(mgr, &key);
|
||||
struct ip_flow *flow = ip_reassembly_update_flow(mgr, &key, now_sec);
|
||||
if (flow == NULL)
|
||||
{
|
||||
return NULL;
|
||||
@@ -1010,9 +978,9 @@ struct packet *ipv4_reassembly_packet(struct ip_reassembly *mgr, const struct pa
|
||||
* +-----------------+-----------------+--------+--------+-//-+--------+
|
||||
*/
|
||||
|
||||
struct packet *ipv6_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt)
|
||||
struct packet *ipv6_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now_sec)
|
||||
{
|
||||
const struct layer_record *layer = pkt->frag_layer;
|
||||
const struct layer *layer = pkt->frag_layer;
|
||||
const struct ip6_hdr *hdr = (const struct ip6_hdr *)layer->hdr_ptr;
|
||||
const struct ip6_frag *frag_hdr = ipv6_hdr_get_frag_ext(hdr);
|
||||
if (frag_hdr == NULL)
|
||||
@@ -1035,7 +1003,7 @@ struct packet *ipv6_reassembly_packet(struct ip_reassembly *mgr, const struct pa
|
||||
key.ip_id = ipv6_frag_get_ident(frag_hdr);
|
||||
key.proto = 0; // only first fragment has the upper layer protocol
|
||||
|
||||
struct ip_flow *flow = ip_reassembly_update_flow(mgr, &key);
|
||||
struct ip_flow *flow = ip_reassembly_update_flow(mgr, &key, now_sec);
|
||||
if (flow == NULL)
|
||||
{
|
||||
return NULL;
|
||||
|
||||
Reference in New Issue
Block a user