Template
1
0
mirror of https://github.com/bol-van/zapret2.git synced 2026-03-14 06:13:09 +00:00
Files
zapret2/nfq2/conntrack.h
2026-02-19 17:38:46 +03:00

121 lines
4.0 KiB
C

#pragma once
// this conntrack is not bullet-proof
// its designed to satisfy dpi desync needs only
#include <stdbool.h>
#include <stdint.h>
#include <ctype.h>
#include <sys/types.h>
#include <netinet/in.h>
#define __FAVOR_BSD
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include "conntrack_base.h"
#include "packet_queue.h"
#include "protocol.h"
#include "darkmagic.h"
//#define HASH_BLOOM 20
#define HASH_NONFATAL_OOM 1
#undef HASH_FUNCTION
#define HASH_FUNCTION HASH_BER
#include "uthash.h"
#define RETRANS_COUNTER_STOP ((uint8_t)-1)
typedef union {
struct in_addr ip;
struct in6_addr ip6;
} t_addr;
typedef struct
{
t_addr src, dst;
uint16_t sport,dport;
uint8_t l3proto; // IPPROTO_IP, IPPROTO_IPV6
uint8_t l4proto; // IPPROTO_TCP, IPPROTO_UDP
} t_conn;
// this structure helps to reassemble continuous packets streams. it does not support out-of-orders
typedef struct {
uint8_t *packet; // allocated for size during reassemble request. requestor must know the message size.
uint32_t seq; // current seq number. if a packet comes with unsupported seq overlap - it fails reassemble session.
size_t size; // expected message size. success means that we have received exactly 'size' bytes and have them in 'packet'
size_t size_present; // how many bytes already stored in 'packet'
} t_reassemble;
typedef struct
{
bool bCheckDone, bCheckResult, bCheckExcluded; // hostlist check result cache
struct timespec t_start;
// this block of data can change between delayed (queued) packets. need to remeber this data for each packet for further replay
t_ctrack_positions pos;
struct desync_profile *dp; // desync profile cache
bool dp_search_complete;
uint8_t req_retrans_counter; // number of request retransmissions
bool failure_detect_finalized;
uint8_t incoming_ttl;
bool b_cutoff; // mark for deletion
bool b_lua_in_cutoff,b_lua_out_cutoff;
t_l7proto l7proto;
bool l7proto_discovered;
char *hostname;
bool hostname_is_ip;
bool hostname_discovered;
bool hostname_ah_check; // should perform autohostlist checks
int lua_state; // registry index of associated LUA object
int lua_instance_cutoff; // registry index of per connection function instance cutoff table
t_reassemble reasm_client;
struct rawpacket_tailhead delayed;
} t_ctrack;
typedef struct
{
t_ctrack track;
UT_hash_handle hh; // makes this structure hashable
t_conn conn; // key
} t_conntrack_pool;
typedef struct
{
// inactivity time to purge an entry in each connection state
uint32_t timeout_syn,timeout_established,timeout_fin,timeout_udp;
time_t t_purge_interval, t_last_purge;
t_conntrack_pool *pool;
} t_conntrack;
void ConntrackPoolInit(t_conntrack *p, time_t purge_interval, uint32_t timeout_syn, uint32_t timeout_established, uint32_t timeout_fin, uint32_t timeout_udp);
void ConntrackPoolDestroy(t_conntrack *p);
bool ConntrackPoolFeed(t_conntrack *p, const struct dissect *dis, t_ctrack **ctrack, bool *bReverse);
// do not create, do not update. only find existing
bool ConntrackPoolDoubleSearch(t_conntrack *p, const struct dissect *dis, t_ctrack **ctrack, bool *bReverse);
bool ConntrackPoolDrop(t_conntrack *p, const struct dissect *dis);
bool ConntrackExtractConn(t_conn *c, bool bReverse, const struct dissect *dis);
void ConntrackPoolDump(const t_conntrack *p);
void ConntrackPoolPurge(t_conntrack *p);
void ConntrackClearHostname(t_ctrack *track);
bool ReasmInit(t_reassemble *reasm, size_t size_requested, uint32_t seq_start);
bool ReasmResize(t_reassemble *reasm, size_t new_size);
void ReasmClear(t_reassemble *reasm);
// false means reassemble session has failed and we should ReasmClear() it
bool ReasmFeed(t_reassemble *reasm, uint32_t seq, const void *payload, size_t len);
// check if it has enough space to buffer 'len' bytes
bool ReasmHasSpace(t_reassemble *reasm, size_t len);
inline static bool ReasmIsEmpty(t_reassemble *reasm) {return !reasm->size;}
inline static bool ReasmIsFull(t_reassemble *reasm) {return !ReasmIsEmpty(reasm) && (reasm->size==reasm->size_present);}