mirror of
https://github.com/bol-van/zapret2.git
synced 2026-03-14 06:13:09 +00:00
nfqws2,zapret-auto: reset retransmitter
This commit is contained in:
@@ -130,3 +130,5 @@ v0.7.6
|
||||
|
||||
* nfqws2: reevaluate profile on l7/host discovery in any direction
|
||||
* nfqws2: dtls protocol detection
|
||||
* nfqws2: autohostlist reset retransmitter to break long wait
|
||||
* zapret-auto: stadard_failure_detector reset retransmitter to break long wait
|
||||
|
||||
@@ -158,6 +158,10 @@ function standard_failure_detector(desync, crec)
|
||||
dis_reverse(dis)
|
||||
dis.tcp.th_flags = TH_RST
|
||||
dis.tcp.th_win = desync.track and desync.track.pos.reverse.tcp.winsize or 64
|
||||
dis.tcp.options = {}
|
||||
if dis.ip6 then
|
||||
dis.ip6.ip6_flow = desync.track.pos.reverse.ip6_flow
|
||||
end
|
||||
DLOG("standard_failure_detector: sending RST to retransmitter")
|
||||
rawsend_dissect(dis)
|
||||
end
|
||||
|
||||
@@ -764,29 +764,18 @@ end
|
||||
|
||||
-- reverses ip addresses, ports and seq/ack
|
||||
function dis_reverse(dis)
|
||||
local temp
|
||||
if dis.ip then
|
||||
temp = dis.ip.ip_src
|
||||
dis.ip.ip_src = dis.ip.ip_dst
|
||||
dis.ip.ip_dst = temp
|
||||
dis.ip.ip_src, dis.ip.ip_dst = dis.ip.ip_dst, dis.ip.ip_src
|
||||
end
|
||||
if dis.ip6 then
|
||||
temp = dis.ip6.ip6_src
|
||||
dis.ip6.ip6_src = dis.ip6.ip6_dst
|
||||
dis.ip6.ip6_dst = temp
|
||||
dis.ip6.ip6_src, dis.ip6.ip6_dst = dis.ip6.ip6_dst, dis.ip6.ip6_src
|
||||
end
|
||||
if dis.tcp then
|
||||
temp = dis.tcp.th_sport
|
||||
dis.tcp.th_sport = dis.tcp.th_dport
|
||||
dis.tcp.th_dport = temp
|
||||
temp = dis.tcp.th_ack
|
||||
dis.tcp.th_ack = dis.tcp.th_seq
|
||||
dis.tcp.th_seq = temp
|
||||
dis.tcp.th_sport, dis.tcp.th_dport = dis.tcp.th_dport, dis.tcp.th_sport
|
||||
dis.tcp.th_ack, dis.tcp.th_seq = dis.tcp.th_seq, dis.tcp.th_ack
|
||||
end
|
||||
if dis.udp then
|
||||
temp = dis.udp.uh_sport
|
||||
dis.udp.uh_sport = dis.udp.uh_dport
|
||||
dis.udp.uh_dport = temp
|
||||
dis.udp.uh_sport, dis.udp.uh_dport = dis.udp.uh_dport, dis.udp.uh_sport
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -70,24 +70,24 @@ void ConntrackPoolInit(t_conntrack *p, time_t purge_interval, uint32_t timeout_s
|
||||
p->pool = NULL;
|
||||
}
|
||||
|
||||
void ConntrackExtractConn(t_conn *c, bool bReverse, const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcphdr, const struct udphdr *udphdr)
|
||||
void ConntrackExtractConn(t_conn *c, bool bReverse, const struct dissect *dis)
|
||||
{
|
||||
memset(c, 0, sizeof(*c));
|
||||
if (ip)
|
||||
if (dis->ip)
|
||||
{
|
||||
c->l3proto = IPPROTO_IP;
|
||||
c->dst.ip = bReverse ? ip->ip_src : ip->ip_dst;
|
||||
c->src.ip = bReverse ? ip->ip_dst : ip->ip_src;
|
||||
c->dst.ip = bReverse ? dis->ip->ip_src : dis->ip->ip_dst;
|
||||
c->src.ip = bReverse ? dis->ip->ip_dst : dis->ip->ip_src;
|
||||
}
|
||||
else if (ip6)
|
||||
else if (dis->ip6)
|
||||
{
|
||||
c->l3proto = IPPROTO_IPV6;
|
||||
c->dst.ip6 = bReverse ? ip6->ip6_src : ip6->ip6_dst;
|
||||
c->src.ip6 = bReverse ? ip6->ip6_dst : ip6->ip6_src;
|
||||
c->dst.ip6 = bReverse ? dis->ip6->ip6_src : dis->ip6->ip6_dst;
|
||||
c->src.ip6 = bReverse ? dis->ip6->ip6_dst : dis->ip6->ip6_src;
|
||||
}
|
||||
else
|
||||
c->l3proto = -1;
|
||||
extract_ports(tcphdr, udphdr, &c->l4proto, bReverse ? &c->dport : &c->sport, bReverse ? &c->sport : &c->dport);
|
||||
extract_ports(dis->tcp, dis->udp, &c->l4proto, bReverse ? &c->dport : &c->sport, bReverse ? &c->sport : &c->dport);
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ static t_conntrack_pool *ConntrackNew(t_conntrack_pool **pp, const t_conn *c)
|
||||
return ctnew;
|
||||
}
|
||||
|
||||
static void ConntrackApplyPos(const struct tcphdr *tcp, t_ctrack *t, bool bReverse, uint32_t len_payload)
|
||||
static void ConntrackApplyPos(t_ctrack *t, bool bReverse, const struct dissect *dis)
|
||||
{
|
||||
uint8_t scale;
|
||||
uint16_t mss;
|
||||
@@ -136,21 +136,23 @@ static void ConntrackApplyPos(const struct tcphdr *tcp, t_ctrack *t, bool bRever
|
||||
direct = bReverse ? &t->pos.server : &t->pos.client;
|
||||
reverse = bReverse ? &t->pos.client : &t->pos.server;
|
||||
|
||||
scale = tcp_find_scale_factor(tcp);
|
||||
mss = ntohs(tcp_find_mss(tcp));
|
||||
if (dis->ip6) direct->ip6flow = ntohl(dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_flow);
|
||||
|
||||
direct->seq_last = ntohl(tcp->th_seq);
|
||||
direct->pos = direct->seq_last + len_payload;
|
||||
reverse->pos = reverse->seq_last = ntohl(tcp->th_ack);
|
||||
scale = tcp_find_scale_factor(dis->tcp);
|
||||
mss = ntohs(tcp_find_mss(dis->tcp));
|
||||
|
||||
direct->seq_last = ntohl(dis->tcp->th_seq);
|
||||
direct->pos = direct->seq_last + dis->len_payload;
|
||||
reverse->pos = reverse->seq_last = ntohl(dis->tcp->th_ack);
|
||||
if (t->pos.state == SYN)
|
||||
direct->uppos_prev = direct->uppos = direct->pos;
|
||||
else if (len_payload)
|
||||
else if (dis->len_payload)
|
||||
{
|
||||
direct->uppos_prev = direct->uppos;
|
||||
if (!((direct->pos - direct->uppos) & 0x80000000))
|
||||
direct->uppos = direct->pos;
|
||||
}
|
||||
direct->winsize = ntohs(tcp->th_win);
|
||||
direct->winsize = ntohs(dis->tcp->th_win);
|
||||
direct->winsize_calc = direct->winsize;
|
||||
if (direct->scale != SCALE_NONE) direct->winsize_calc <<= direct->scale;
|
||||
if (mss && !direct->mss) direct->mss = mss;
|
||||
@@ -162,8 +164,7 @@ static void ConntrackApplyPos(const struct tcphdr *tcp, t_ctrack *t, bool bRever
|
||||
reverse->rseq_over_2G = true;
|
||||
}
|
||||
|
||||
// non-tcp packets are passed with tcphdr=NULL but len_payload filled
|
||||
static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct tcphdr *tcphdr, uint32_t len_payload)
|
||||
static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct dissect *dis)
|
||||
{
|
||||
uint8_t scale;
|
||||
uint16_t mss;
|
||||
@@ -171,34 +172,34 @@ static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct tcphdr
|
||||
if (bReverse)
|
||||
{
|
||||
t->pos.server.pcounter++;
|
||||
t->pos.server.pdcounter += !!len_payload;
|
||||
t->pos.server.pbcounter += len_payload;
|
||||
t->pos.server.pdcounter += !!dis->len_payload;
|
||||
t->pos.server.pbcounter += dis->len_payload;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
t->pos.client.pcounter++;
|
||||
t->pos.client.pdcounter += !!len_payload;
|
||||
t->pos.client.pbcounter += len_payload;
|
||||
t->pos.client.pdcounter += !!dis->len_payload;
|
||||
t->pos.client.pbcounter += dis->len_payload;
|
||||
}
|
||||
|
||||
if (tcphdr)
|
||||
if (dis->tcp)
|
||||
{
|
||||
if (tcp_syn_segment(tcphdr))
|
||||
if (tcp_syn_segment(dis->tcp))
|
||||
{
|
||||
if (t->pos.state != SYN) ConntrackReInitTrack(t); // erase current entry
|
||||
t->pos.client.seq0 = ntohl(tcphdr->th_seq);
|
||||
t->pos.client.seq0 = ntohl(dis->tcp->th_seq);
|
||||
}
|
||||
else if (tcp_synack_segment(tcphdr))
|
||||
else if (tcp_synack_segment(dis->tcp))
|
||||
{
|
||||
// ignore SA dups
|
||||
uint32_t seq0 = ntohl(tcphdr->th_ack) - 1;
|
||||
uint32_t seq0 = ntohl(dis->tcp->th_ack) - 1;
|
||||
if (t->pos.state != SYN && t->pos.client.seq0 != seq0)
|
||||
ConntrackReInitTrack(t); // erase current entry
|
||||
if (!t->pos.client.seq0) t->pos.client.seq0 = seq0;
|
||||
t->pos.server.seq0 = ntohl(tcphdr->th_seq);
|
||||
t->pos.server.seq0 = ntohl(dis->tcp->th_seq);
|
||||
}
|
||||
else if (tcphdr->th_flags & (TH_FIN | TH_RST))
|
||||
else if (dis->tcp->th_flags & (TH_FIN | TH_RST))
|
||||
{
|
||||
t->pos.state = FIN;
|
||||
}
|
||||
@@ -207,11 +208,11 @@ static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct tcphdr
|
||||
if (t->pos.state == SYN)
|
||||
{
|
||||
t->pos.state = ESTABLISHED;
|
||||
if (!bReverse && !t->pos.server.seq0) t->pos.server.seq0 = ntohl(tcphdr->th_ack) - 1;
|
||||
if (!bReverse && !t->pos.server.seq0) t->pos.server.seq0 = ntohl(dis->tcp->th_ack) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
ConntrackApplyPos(tcphdr, t, bReverse, len_payload);
|
||||
ConntrackApplyPos(t, bReverse, dis);
|
||||
}
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &t->pos.t_last);
|
||||
@@ -219,12 +220,12 @@ static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct tcphdr
|
||||
if (!t->t_start.tv_sec) t->t_start = t->pos.t_last;
|
||||
}
|
||||
|
||||
static bool ConntrackPoolDoubleSearchPool(t_conntrack_pool **pp, const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcphdr, const struct udphdr *udphdr, t_ctrack **ctrack, bool *bReverse)
|
||||
static bool ConntrackPoolDoubleSearchPool(t_conntrack_pool **pp, const struct dissect *dis, t_ctrack **ctrack, bool *bReverse)
|
||||
{
|
||||
t_conn conn, connswp;
|
||||
t_conntrack_pool *ctr;
|
||||
|
||||
ConntrackExtractConn(&conn, false, ip, ip6, tcphdr, udphdr);
|
||||
ConntrackExtractConn(&conn, false, dis);
|
||||
if ((ctr = ConntrackPoolSearch(*pp, &conn)))
|
||||
{
|
||||
if (bReverse) *bReverse = false;
|
||||
@@ -243,22 +244,22 @@ static bool ConntrackPoolDoubleSearchPool(t_conntrack_pool **pp, const struct ip
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool ConntrackPoolDoubleSearch(t_conntrack *p, const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcphdr, const struct udphdr *udphdr, t_ctrack **ctrack, bool *bReverse)
|
||||
bool ConntrackPoolDoubleSearch(t_conntrack *p, const struct dissect *dis, t_ctrack **ctrack, bool *bReverse)
|
||||
{
|
||||
return ConntrackPoolDoubleSearchPool(&p->pool, ip, ip6, tcphdr, udphdr, ctrack, bReverse);
|
||||
return ConntrackPoolDoubleSearchPool(&p->pool, dis, ctrack, bReverse);
|
||||
}
|
||||
|
||||
static bool ConntrackPoolFeedPool(t_conntrack_pool **pp, const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcphdr, const struct udphdr *udphdr, size_t len_payload, t_ctrack **ctrack, bool *bReverse)
|
||||
static bool ConntrackPoolFeedPool(t_conntrack_pool **pp, const struct dissect *dis, t_ctrack **ctrack, bool *bReverse)
|
||||
{
|
||||
t_conn conn, connswp;
|
||||
t_conntrack_pool *ctr;
|
||||
bool b_rev;
|
||||
uint8_t proto = tcphdr ? IPPROTO_TCP : udphdr ? IPPROTO_UDP : IPPROTO_NONE;
|
||||
uint8_t proto = dis->tcp ? IPPROTO_TCP : dis->udp ? IPPROTO_UDP : IPPROTO_NONE;
|
||||
|
||||
ConntrackExtractConn(&conn, false, ip, ip6, tcphdr, udphdr);
|
||||
ConntrackExtractConn(&conn, false, dis);
|
||||
if ((ctr = ConntrackPoolSearch(*pp, &conn)))
|
||||
{
|
||||
ConntrackFeedPacket(&ctr->track, (b_rev = false), tcphdr, len_payload);
|
||||
ConntrackFeedPacket(&ctr->track, (b_rev = false), dis);
|
||||
goto ok;
|
||||
}
|
||||
else
|
||||
@@ -266,16 +267,16 @@ static bool ConntrackPoolFeedPool(t_conntrack_pool **pp, const struct ip *ip, co
|
||||
connswap(&conn, &connswp);
|
||||
if ((ctr = ConntrackPoolSearch(*pp, &connswp)))
|
||||
{
|
||||
ConntrackFeedPacket(&ctr->track, (b_rev = true), tcphdr, len_payload);
|
||||
ConntrackFeedPacket(&ctr->track, (b_rev = true), dis);
|
||||
goto ok;
|
||||
}
|
||||
}
|
||||
b_rev = tcphdr && tcp_synack_segment(tcphdr);
|
||||
if ((tcphdr && tcp_syn_segment(tcphdr)) || b_rev || udphdr)
|
||||
b_rev = dis->tcp && tcp_synack_segment(dis->tcp);
|
||||
if ((dis->tcp && tcp_syn_segment(dis->tcp)) || b_rev || dis->udp)
|
||||
{
|
||||
if ((ctr = ConntrackNew(pp, b_rev ? &connswp : &conn)))
|
||||
{
|
||||
ConntrackFeedPacket(&ctr->track, b_rev, tcphdr, len_payload);
|
||||
ConntrackFeedPacket(&ctr->track, b_rev, dis);
|
||||
goto ok;
|
||||
}
|
||||
}
|
||||
@@ -286,16 +287,16 @@ ok:
|
||||
if (bReverse) *bReverse = b_rev;
|
||||
return true;
|
||||
}
|
||||
bool ConntrackPoolFeed(t_conntrack *p, const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcphdr, const struct udphdr *udphdr, size_t len_payload, t_ctrack **ctrack, bool *bReverse)
|
||||
bool ConntrackPoolFeed(t_conntrack *p, const struct dissect *dis, t_ctrack **ctrack, bool *bReverse)
|
||||
{
|
||||
return ConntrackPoolFeedPool(&p->pool, ip, ip6, tcphdr, udphdr, len_payload, ctrack, bReverse);
|
||||
return ConntrackPoolFeedPool(&p->pool, dis, ctrack, bReverse);
|
||||
}
|
||||
|
||||
static bool ConntrackPoolDropPool(t_conntrack_pool **pp, const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcphdr, const struct udphdr *udphdr)
|
||||
static bool ConntrackPoolDropPool(t_conntrack_pool **pp, const struct dissect *dis)
|
||||
{
|
||||
t_conn conn, connswp;
|
||||
t_conntrack_pool *t;
|
||||
ConntrackExtractConn(&conn, false, ip, ip6, tcphdr, udphdr);
|
||||
ConntrackExtractConn(&conn, false, dis);
|
||||
if (!(t = ConntrackPoolSearch(*pp, &conn)))
|
||||
{
|
||||
connswap(&conn, &connswp);
|
||||
@@ -305,9 +306,9 @@ static bool ConntrackPoolDropPool(t_conntrack_pool **pp, const struct ip *ip, co
|
||||
HASH_DEL(*pp, t); ConntrackFreeElem(t);
|
||||
return true;
|
||||
}
|
||||
bool ConntrackPoolDrop(t_conntrack *p, const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcphdr, const struct udphdr *udphdr)
|
||||
bool ConntrackPoolDrop(t_conntrack *p, const struct dissect *dis)
|
||||
{
|
||||
return ConntrackPoolDropPool(&p->pool, ip, ip6, tcphdr, udphdr);
|
||||
return ConntrackPoolDropPool(&p->pool, dis);
|
||||
}
|
||||
|
||||
void ConntrackPoolPurge(t_conntrack *p)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "conntrack_base.h"
|
||||
#include "packet_queue.h"
|
||||
#include "protocol.h"
|
||||
#include "darkmagic.h"
|
||||
|
||||
//#define HASH_BLOOM 20
|
||||
#define HASH_NONFATAL_OOM 1
|
||||
@@ -100,11 +101,11 @@ typedef struct
|
||||
|
||||
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 ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcphdr, const struct udphdr *udphdr, size_t len_payload, t_ctrack **ctrack, bool *bReverse);
|
||||
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 ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcphdr, const struct udphdr *udphdr, t_ctrack **ctrack, bool *bReverse);
|
||||
bool ConntrackPoolDrop(t_conntrack *p, const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcphdr, const struct udphdr *udphdr);
|
||||
void CaonntrackExtractConn(t_conn *c, bool bReverse, const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcphdr, const struct udphdr *udphdr);
|
||||
bool ConntrackPoolDoubleSearch(t_conntrack *p, const struct dissect *dis, t_ctrack **ctrack, bool *bReverse);
|
||||
bool ConntrackPoolDrop(t_conntrack *p, const struct dissect *dis);
|
||||
void 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);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#define CTRACK_T_SYN 60
|
||||
@@ -17,6 +18,7 @@ typedef struct
|
||||
uint64_t pcounter; // packet counter
|
||||
uint64_t pdcounter; // data packet counter (with payload)
|
||||
uint64_t pbcounter; // transferred byte counter. includes retransmissions. it's not the same as relative seq.
|
||||
uint32_t ip6flow;
|
||||
|
||||
// tcp only state, not used in udp
|
||||
uint32_t pos; // TCP: seq_last+payload, ack_last+payload UDP: sum of all seen payload lenghts including current
|
||||
|
||||
@@ -547,6 +547,33 @@ void proto_dissect_l3l4(const uint8_t *data, size_t len, struct dissect *dis)
|
||||
}
|
||||
}
|
||||
|
||||
void reverse_ip(struct ip *ip, struct ip6_hdr *ip6)
|
||||
{
|
||||
if (ip)
|
||||
{
|
||||
struct in_addr temp = ip->ip_src;
|
||||
ip->ip_src = ip->ip_dst;
|
||||
ip->ip_dst = temp;
|
||||
ip4_fix_checksum(ip);
|
||||
}
|
||||
if (ip6)
|
||||
{
|
||||
struct in6_addr temp = ip6->ip6_src;
|
||||
ip6->ip6_src = ip6->ip6_dst;
|
||||
ip6->ip6_dst = temp;
|
||||
}
|
||||
}
|
||||
void reverse_tcp(struct tcphdr *tcp)
|
||||
{
|
||||
uint16_t tport = tcp->th_sport;
|
||||
tcp->th_sport = tcp->th_dport;
|
||||
tcp->th_dport = tport;
|
||||
|
||||
uint32_t tseq = tcp->th_seq;
|
||||
tcp->th_seq = tcp->th_ack;
|
||||
tcp->th_ack = tseq;
|
||||
}
|
||||
|
||||
|
||||
uint8_t ttl46(const struct ip *ip, const struct ip6_hdr *ip6)
|
||||
{
|
||||
|
||||
@@ -162,6 +162,8 @@ struct dissect
|
||||
size_t len_payload;
|
||||
};
|
||||
void proto_dissect_l3l4(const uint8_t *data, size_t len, struct dissect *dis);
|
||||
void reverse_ip(struct ip *ip, struct ip6_hdr *ip6);
|
||||
void reverse_tcp(struct tcphdr *tcp);
|
||||
|
||||
uint8_t ttl46(const struct ip *ip, const struct ip6_hdr *ip6);
|
||||
|
||||
|
||||
@@ -246,11 +246,13 @@ static bool is_retransmission(const t_ctrack_position *pos)
|
||||
}
|
||||
|
||||
// return true if retrans trigger fires
|
||||
static bool auto_hostlist_retrans(t_ctrack *ctrack, uint8_t l4proto, int threshold, const char *client_ip_port, t_l7proto l7proto)
|
||||
static bool auto_hostlist_retrans
|
||||
(t_ctrack *ctrack, const struct dissect *dis, int threshold, const char *client_ip_port, t_l7proto l7proto,
|
||||
const struct sockaddr *client, const char *ifclient)
|
||||
{
|
||||
if (ctrack && ctrack->dp && ctrack->hostname_ah_check && !ctrack->failure_detect_finalized && ctrack->req_retrans_counter != RETRANS_COUNTER_STOP)
|
||||
{
|
||||
if (l4proto == IPPROTO_TCP && ctrack->pos.state!=SYN)
|
||||
if (dis->proto == IPPROTO_TCP && ctrack->pos.state!=SYN)
|
||||
{
|
||||
if (!seq_within(ctrack->pos.client.seq_last, ctrack->pos.client.seq0, ctrack->pos.client.seq0 + ctrack->dp->hostlist_auto_retrans_maxseq))
|
||||
{
|
||||
@@ -269,6 +271,46 @@ static bool auto_hostlist_retrans(t_ctrack *ctrack, uint8_t l4proto, int thresho
|
||||
DLOG("retrans threshold reached : %u/%u\n", ctrack->req_retrans_counter, threshold);
|
||||
ctrack_stop_retrans_counter(ctrack);
|
||||
ctrack->failure_detect_finalized = true;
|
||||
if (dis->tcp && ctrack->dp->hostlist_auto_retrans_reset && (dis->ip || dis->ip6))
|
||||
{
|
||||
uint8_t pkt[sizeof(struct ip6_hdr)+sizeof(struct tcphdr)];
|
||||
struct ip *ip;
|
||||
struct ip6_hdr *ip6;
|
||||
struct tcphdr *tcp;
|
||||
uint16_t pktlen;
|
||||
|
||||
if (dis->ip)
|
||||
{
|
||||
ip = (struct ip*)pkt; ip6=NULL;
|
||||
pktlen = sizeof(struct iphdr) + sizeof(struct tcphdr);
|
||||
*ip = *dis->ip;
|
||||
ip->ip_hl = sizeof(struct iphdr)/4; // remove ip options
|
||||
ip->ip_len = htons(pktlen);
|
||||
ip->ip_id=0;
|
||||
tcp = (struct tcphdr*)(ip+1);
|
||||
*tcp = *dis->tcp;
|
||||
}
|
||||
else if (dis->ip6)
|
||||
{
|
||||
ip6 = (struct ip6_hdr*)pkt; ip=NULL;
|
||||
pktlen = sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
|
||||
*ip6 = *dis->ip6;
|
||||
ip6->ip6_plen = htons(sizeof(struct tcphdr));
|
||||
ip6->ip6_nxt = IPPROTO_TCP;
|
||||
ip6->ip6_ctlun.ip6_un1.ip6_un1_flow = htonl(ctrack->pos.server.ip6flow);
|
||||
tcp = (struct tcphdr*)(ip6+1);
|
||||
*tcp = *dis->tcp;
|
||||
}
|
||||
reverse_ip(ip,ip6); // also fixes ip4 checksum
|
||||
reverse_tcp(tcp);
|
||||
tcp->th_off = sizeof(struct tcphdr)/4; // remove tcp options
|
||||
tcp->th_flags = TH_RST;
|
||||
tcp->th_win = ctrack->pos.server.winsize;
|
||||
tcp_fix_checksum(tcp, sizeof(struct tcphdr), ip, ip6);
|
||||
|
||||
DLOG("sending RST to retransmitter\n");
|
||||
rawsend(client,0,ifclient,pkt,pktlen);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
DLOG("retrans counter : %u/%u\n", ctrack->req_retrans_counter, threshold);
|
||||
@@ -330,13 +372,13 @@ static void fill_client_ip_port(const struct sockaddr *client, char *client_ip_p
|
||||
else
|
||||
*client_ip_port = 0;
|
||||
}
|
||||
static void process_retrans_fail(t_ctrack *ctrack, uint8_t proto, const struct sockaddr *client)
|
||||
static void process_retrans_fail(t_ctrack *ctrack, const struct dissect *dis, struct sockaddr *client, const char *ifclient)
|
||||
{
|
||||
if (params.server) return; // no autohostlists in server mode
|
||||
|
||||
char client_ip_port[48];
|
||||
fill_client_ip_port(client, client_ip_port, sizeof(client_ip_port));
|
||||
if (ctrack && ctrack->dp && ctrack->hostname && auto_hostlist_retrans(ctrack, proto, ctrack->dp->hostlist_auto_retrans_threshold, client_ip_port, ctrack->l7proto))
|
||||
if (ctrack && ctrack->dp && ctrack->hostname && auto_hostlist_retrans(ctrack, dis, ctrack->dp->hostlist_auto_retrans_threshold, client_ip_port, ctrack->l7proto, client, ifclient))
|
||||
{
|
||||
HOSTLIST_DEBUGLOG_APPEND("%s : profile %u (%s) : client %s : proto %s : retrans threshold reached", ctrack->hostname, ctrack->dp->n, PROFILE_NAME(ctrack->dp), client_ip_port, l7proto_str(ctrack->l7proto));
|
||||
auto_hostlist_failed(ctrack->dp, ctrack->hostname, ctrack->hostname_is_ip, client_ip_port, ctrack->l7proto);
|
||||
@@ -1036,7 +1078,7 @@ static uint8_t dpi_desync_tcp_packet_play(
|
||||
// in replay mode conntrack_replay is not NULL and ctrack is NULL
|
||||
|
||||
//ConntrackPoolDump(¶ms.conntrack);
|
||||
if (!ConntrackPoolDoubleSearch(¶ms.conntrack, dis->ip, dis->ip6, dis->tcp, NULL, &ctrack_replay, &bReverse) || bReverse)
|
||||
if (!ConntrackPoolDoubleSearch(¶ms.conntrack, dis, &ctrack_replay, &bReverse) || bReverse)
|
||||
return verdict;
|
||||
bReverseFixed = bReverse ^ params.server;
|
||||
setup_direction(dis, bReverseFixed, &src, &dst, &sdip4, &sdip6, &sdport);
|
||||
@@ -1068,7 +1110,7 @@ static uint8_t dpi_desync_tcp_packet_play(
|
||||
if (!params.ctrack_disable)
|
||||
{
|
||||
ConntrackPoolPurge(¶ms.conntrack);
|
||||
if (ConntrackPoolFeed(¶ms.conntrack, dis->ip, dis->ip6, dis->tcp, NULL, dis->len_payload, &ctrack, &bReverse))
|
||||
if (ConntrackPoolFeed(¶ms.conntrack, dis, &ctrack, &bReverse))
|
||||
{
|
||||
dp = ctrack->dp;
|
||||
ctrack_replay = ctrack;
|
||||
@@ -1228,7 +1270,7 @@ static uint8_t dpi_desync_tcp_packet_play(
|
||||
rlen_payload = ctrack->reasm_client.size_present;
|
||||
}
|
||||
|
||||
process_retrans_fail(ctrack, IPPROTO_TCP, (struct sockaddr*)&src);
|
||||
process_retrans_fail(ctrack, dis, (struct sockaddr*)&src, ifin);
|
||||
if (IsHttp(rdata_payload, rlen_payload))
|
||||
{
|
||||
DLOG("packet contains HTTP request\n");
|
||||
@@ -1498,7 +1540,7 @@ static uint8_t dpi_desync_udp_packet_play(
|
||||
// in replay mode conntrack_replay is not NULL and ctrack is NULL
|
||||
|
||||
//ConntrackPoolDump(¶ms.conntrack);
|
||||
if (!ConntrackPoolDoubleSearch(¶ms.conntrack, dis->ip, dis->ip6, NULL, dis->udp, &ctrack_replay, &bReverse) || bReverse)
|
||||
if (!ConntrackPoolDoubleSearch(¶ms.conntrack, dis, &ctrack_replay, &bReverse) || bReverse)
|
||||
return verdict;
|
||||
bReverseFixed = bReverse ^ params.server;
|
||||
setup_direction(dis, bReverseFixed, &src, &dst, &sdip4, &sdip6, &sdport);
|
||||
@@ -1530,7 +1572,7 @@ static uint8_t dpi_desync_udp_packet_play(
|
||||
if (!params.ctrack_disable)
|
||||
{
|
||||
ConntrackPoolPurge(¶ms.conntrack);
|
||||
if (ConntrackPoolFeed(¶ms.conntrack, dis->ip, dis->ip6, NULL, dis->udp, dis->len_payload, &ctrack, &bReverse))
|
||||
if (ConntrackPoolFeed(¶ms.conntrack, dis, &ctrack, &bReverse))
|
||||
{
|
||||
dp = ctrack->dp;
|
||||
ctrack_replay = ctrack;
|
||||
@@ -1836,13 +1878,8 @@ static uint8_t dpi_desync_udp_packet_play(
|
||||
ctrack_replay->bCheckExcluded = bCheckExcluded;
|
||||
}
|
||||
}
|
||||
if (bCheckResult)
|
||||
ctrack_stop_retrans_counter(ctrack_replay);
|
||||
else
|
||||
{
|
||||
if (ctrack_replay)
|
||||
ctrack_replay->hostname_ah_check = dp->hostlist_auto && !bCheckExcluded;
|
||||
}
|
||||
if (!bCheckResult && ctrack_replay)
|
||||
ctrack_replay->hostname_ah_check = dp->hostlist_auto && !bCheckExcluded;
|
||||
}
|
||||
|
||||
process_udp_fail(ctrack_replay, tpos, (struct sockaddr*)&src);
|
||||
|
||||
@@ -1279,7 +1279,7 @@ void lua_pushf_ctrack_pos(const t_ctrack *ctrack, const t_ctrack_position *pos)
|
||||
if (ctrack->ipproto == IPPROTO_TCP)
|
||||
{
|
||||
lua_pushliteral(params.L, "tcp");
|
||||
lua_createtable(params.L, 0, 11);
|
||||
lua_createtable(params.L, 0, 12);
|
||||
lua_pushf_lint("seq0", pos->seq0);
|
||||
lua_pushf_lint("seq", pos->seq_last);
|
||||
lua_pushf_lint("rseq", pos->seq_last - pos->seq0);
|
||||
@@ -1291,6 +1291,7 @@ void lua_pushf_ctrack_pos(const t_ctrack *ctrack, const t_ctrack_position *pos)
|
||||
lua_pushf_int("winsize_calc", pos->winsize_calc);
|
||||
lua_pushf_int("scale", pos->scale);
|
||||
lua_pushf_int("mss", pos->mss);
|
||||
lua_pushf_int("ip6flow", pos->ip6flow);
|
||||
lua_rawset(params.L,-3);
|
||||
}
|
||||
|
||||
|
||||
@@ -1436,6 +1436,7 @@ static void exithelp(void)
|
||||
" --hostlist-auto-fail-time=<int>\t\t\t; all failed attemps must be within these seconds (default : %d)\n"
|
||||
" --hostlist-auto-retrans-threshold=<int>\t\t; how many request retransmissions cause attempt to fail (default : %d)\n"
|
||||
" --hostlist-auto-retrans-maxseq=<int>\t\t\t; count retransmissions only within this relative sequence (default : %u)\n"
|
||||
" --hostlist-auto-retrans-reset=[0|1]\t\t\t; send RST to retransmitter to break long wait (default: 1)\n"
|
||||
" --hostlist-auto-incoming-maxseq=<int>\t\t\t; treat tcp connection as successful if incoming relative sequence exceedes this threshold (default : %u)\n"
|
||||
" --hostlist-auto-udp-out=<int>\t\t\t\t; udp failure condition : sent at least `udp_out` packets (default : %u)\n"
|
||||
" --hostlist-auto-udp-in=<int>\t\t\t\t; udp failure condition : received not more than `udp_in` packets (default : %u)\n"
|
||||
@@ -1554,6 +1555,7 @@ enum opt_indices {
|
||||
IDX_HOSTLIST_AUTO_FAIL_TIME,
|
||||
IDX_HOSTLIST_AUTO_RETRANS_THRESHOLD,
|
||||
IDX_HOSTLIST_AUTO_RETRANS_MAXSEQ,
|
||||
IDX_HOSTLIST_AUTO_RETRANS_RESET,
|
||||
IDX_HOSTLIST_AUTO_INCOMING_MAXSEQ,
|
||||
IDX_HOSTLIST_AUTO_UDP_IN,
|
||||
IDX_HOSTLIST_AUTO_UDP_OUT,
|
||||
@@ -1642,6 +1644,7 @@ static const struct option long_options[] = {
|
||||
[IDX_HOSTLIST_AUTO_FAIL_TIME] = {"hostlist-auto-fail-time", required_argument, 0, 0},
|
||||
[IDX_HOSTLIST_AUTO_RETRANS_THRESHOLD] = {"hostlist-auto-retrans-threshold", required_argument, 0, 0},
|
||||
[IDX_HOSTLIST_AUTO_RETRANS_MAXSEQ] = {"hostlist-auto-retrans-maxseq", required_argument, 0, 0},
|
||||
[IDX_HOSTLIST_AUTO_RETRANS_RESET] = {"hostlist-auto-retrans-reset", optional_argument, 0, 0},
|
||||
[IDX_HOSTLIST_AUTO_INCOMING_MAXSEQ] = {"hostlist-auto-incoming-maxseq", required_argument, 0, 0},
|
||||
[IDX_HOSTLIST_AUTO_UDP_IN] = {"hostlist-auto-udp-in", required_argument, 0, 0},
|
||||
[IDX_HOSTLIST_AUTO_UDP_OUT] = {"hostlist-auto-udp-out", required_argument, 0, 0},
|
||||
@@ -2100,6 +2103,9 @@ int main(int argc, char **argv)
|
||||
case IDX_HOSTLIST_AUTO_INCOMING_MAXSEQ:
|
||||
dp->hostlist_auto_incoming_maxseq = (uint32_t)atoi(optarg);
|
||||
break;
|
||||
case IDX_HOSTLIST_AUTO_RETRANS_RESET:
|
||||
dp->hostlist_auto_retrans_reset = !optarg || !!atoi(optarg);
|
||||
break;
|
||||
case IDX_HOSTLIST_AUTO_UDP_OUT:
|
||||
dp->hostlist_auto_udp_out = atoi(optarg);
|
||||
break;
|
||||
|
||||
@@ -350,6 +350,7 @@ void dp_init(struct desync_profile *dp)
|
||||
dp->hostlist_auto_fail_time = HOSTLIST_AUTO_FAIL_TIME_DEFAULT;
|
||||
dp->hostlist_auto_retrans_threshold = HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT;
|
||||
dp->hostlist_auto_retrans_maxseq = HOSTLIST_AUTO_RETRANS_MAXSEQ;
|
||||
dp->hostlist_auto_retrans_reset = true;
|
||||
dp->hostlist_auto_incoming_maxseq = HOSTLIST_AUTO_INCOMING_MAXSEQ;
|
||||
dp->hostlist_auto_udp_out = HOSTLIST_AUTO_UDP_OUT;
|
||||
dp->hostlist_auto_udp_in = HOSTLIST_AUTO_UDP_IN;
|
||||
|
||||
@@ -84,6 +84,7 @@ struct desync_profile
|
||||
int hostlist_auto_fail_threshold, hostlist_auto_fail_time, hostlist_auto_retrans_threshold;
|
||||
int hostlist_auto_udp_in, hostlist_auto_udp_out;
|
||||
uint32_t hostlist_auto_retrans_maxseq, hostlist_auto_incoming_maxseq;
|
||||
bool hostlist_auto_retrans_reset;
|
||||
|
||||
hostfail_pool *hostlist_auto_fail_counters;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user